[程序源码] OpenCV 图像的简单处理

[复制链接]
 楼主| 一路向北lm 发表于 2018-11-11 13:22 | 显示全部楼层 |阅读模式
1.加载、修改、保存图像
1.1. 加载图像(用 cv::imread)
imread 功能是加载图像文件成为一个 Mat 对象, 其中第一个参数表示图像文件名称第二个参数, 表示加载的图像是什么类型, 支持常见的三个参数值:
IMREAD_UNCHANGED (<0) 表示加载原图, 不做任何改变;
IMREAD_GRAYSCALE ( 0)表示把原图作为灰度图像加载进来;
IMREAD_COLOR (>0) 表示把原图作为 RGB 图像加载进来;
注意: OpenCV 支持 JPG、 PNG、 TIFF 等常见格式图像文件加载  
1.2. 显示图像 (cv::namedWindos 与 cv::imshow)namedWindos 功能是创建一个 OpenCV 窗口, 它是由 OpenCV 自动创建与释放,你无需取销毁它。 常见用法 namedWindow("Window Title", WINDOW_AUTOSIZE)。imshow 根据窗口名称显示图像到指定的窗口上去, 第一个参数是窗口名称, 第二参数是 Mat 对象。
1.3. 修改图像 (cv::cvtColor)cvtColor 的功能是把图像从一个彩色空间转换到另外一个色彩空间, 有三个参数,第一个参数表示源图像、 第二参数表示色彩空间转换之后的图像、 第三个参数表示源和目标色彩空间如: COLOR_BGR2HLS 、 COLOR_BGR2GRAY 等。cvtColor( image, gray_image,COLOR_BGR2GRAY );
1.4. 保存图像(cv::imwrite)
保存图像文件到指定目录路径, 只有 8 位、 16 位的 PNG、 JPG、 Tiff 文件格式而且是单通道或者三通道的 BGR 的图像才可以通过这种方式保存, 保存 PNG 格式的时候可以保存透明通道的图片, 可以指定压缩参数。
参考代码:
  1. /* 基本操作, 加载图像 修改图像, 显示图像, 保存图像 */
  2. int image_open_save()
  3. {
  4. Mat src=imread("E:\\1.png"); // 载入图片
  5. if(!src.data)
  6. {
  7. printf("不能加载图片\r\n");
  8. return -1;
  9. } n
  10. amedWindow("test1",CV_WINDOW_AUTOSIZE); // 新建窗口
  11. imshow("test1",src); // 显示图像
  12. namedWindow("test2"); // 新建窗口
  13. Mat out_image;
  14. cvtColor(src,out_image,COLOR_BGR2GRAY); //图像转换
  15. imshow("test2",out_image); // 显示图像
  16. imwrite("E:\\01.jpg",out_image); // 保存图像
  17. waitKey(0);
  18. }  


 楼主| 一路向北lm 发表于 2018-11-11 13:24 | 显示全部楼层
2.矩阵的掩膜操作  

2.1 获取图像像素指针
CV_Assert(myImage.depth() == CV_8U);Mat.ptr<uchar>(int i=0) 获取像素矩阵的指针, 索引 i 表示第几行, 从 0 开始计行数。获得当前行指针 const uchar* current= myImage.ptr<uchar>(row );获取当前像素点 P(row, col)的像素值 p(row, col) =current[col]

2.2 像素范围处理 saturate_cast<uchar>
saturate_cast<uchar>(-100), 返回 0。
saturate_cast<uchar>(288), 返回 255
saturate_cast<uchar>(100), 返回 100
这个函数的功能是确保 RGB 值得范围在 0~255 之间

2.3 函数调用 filter2D 功能
定义掩膜: Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D( src, dst, src.depth(), kernel );其中 src 与 dst 是 Mat 类型变量、 src.depth 表示位图深度, 有 32、 24、 8 等。

参考代码:
  1. /* 矩阵的掩膜操作 */
  2. int image_deal1()
  3. {
  4. Mat src,dst;
  5. src=imread("E:\\1.png"); // 载入图片
  6. if(!src.data)
  7. {
  8. printf("不能加载图片\r\n");
  9. return -1;
  10. } n
  11. amedWindow("test1",CV_WINDOW_AUTOSIZE); // 新建窗口
  12. imshow("test1",src); // 显示图像
  13. // 定义掩膜
  14. Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
  15. filter2D( src, dst, src.depth(), kernel );
  16. namedWindow("test2"); // 新建窗口
  17. imshow("test2",dst); // 显示图像
  18. waitKey(0);
  19. }



 楼主| 一路向北lm 发表于 2018-11-11 13:27 | 显示全部楼层
3.Mat 对象的使用  

3.1 按照 src 大小尺寸 类型复制 size type
参考代码
  1. Mat dst;
  2. dst = Mat(src.size(),src.type());
  3. dst= Scalar(0,0,100); // 为 BGR 每个通道赋值
  4. namedWindow("output image",CV_WINDOW_AUTOSIZE);
  5. imshow("output image",dst);
3.2 clone 克隆
参考代码
  1. Mat dst = src.clone();
  2. namedWindow("output image",CV_WINDOW_AUTOSIZE);
  3. imshow("output image",dst);
3.3 copyTo 克隆
参考代码:
  1. Mat dst;
  2. src.copyTo(dst);
  3. namedWindow("output image",CV_WINDOW_AUTOSIZE);
  4. imshow("output image",dst);
3.4 图像通道数查看 channels
参考代码:
  1. Mat dst;
  2. cvtColor(src,dst,CV_BGR2GRAY);
  3. printf("input image channels: %d\n",src.channels());
  4. printf("output image channels: %d\n",dst.channels());
3.5 打印灰度图的行数与列数 读取灰度图片某一行数据
参考代码:
  1. int cols = dst.cols;
  2. int rows = dst.rows;
  3. printf("cols: %d, rows: %d\n",cols,rows);
  4. for(int i=0;i<dst.rows;i++)
  5. {
  6. static uchar *firstrow = dst.ptr<uchar>(i);
  7. printf("%d row fiex %d\n",i,*firstrow);
  8. }
3.6 Mat 对象创建
参考代码:
  1. Mat M(3,3,CV_8UC3,Scalar(0,0,255));
  2. cout<<"M:"<< endl <<M << endl;
  3. imshow("output image",M);

  


 楼主| 一路向北lm 发表于 2018-11-11 13:29 | 显示全部楼层
4.图像操作  

4.1 读写单通道像素, 修改单通道像素
参考代码:
  1. // 读取单通道像素 , 修改
  2. Mat dst;
  3. cvtColor(src,dst,CV_BGR2GRAY);
  4. imshow("gray",dst);
  5. int width = dst.cols;
  6. int height = dst.rows;
  7. for(int col=0;col<width;col++)
  8. for(int row=0;row<height;row++)
  9. {
  10. int gray=dst.at<uchar>(row,col);
  11. dst.at<uchar>(row,col) = 255-gray;
  12. }
  13. imshow("grayto",dst);
4.2 读写多通道像素, 修改单通道像素
参考代码
  1. Mat dst;
  2. dst.create(src.size(),src.type());
  3. int width = src.cols;
  4. int height = src.rows;
  5. int nc = src.channels();
  6. for(int col=0;col<width;col++)
  7. for(int row=0;row<height;row++)
  8. {
  9. if(nc==1)
  10. {
  11. int gray=src.at<uchar>(row,col);
  12. src.at<uchar>(row,col) = 255-gray;
  13. }
  14. else if(nc==3)
  15. {
  16. int b =src.at<Vec3b>(row,col)[0];
  17. int g =src.at<Vec3b>(row,col)[1];
  18. int r =src.at<Vec3b>(row,col)[2];
  19. dst.at<Vec3b>(row,col)[0]=255-b;
  20. dst.at<Vec3b>(row,col)[1]=255-g;
  21. dst.at<Vec3b>(row,col)[2]=255-r;
  22. }
  23. }
  24. imshow("grayto",dst);


caijie001 发表于 2018-11-12 14:12 | 显示全部楼层
 楼主| 一路向北lm 发表于 2018-11-12 20:37 | 显示全部楼层
 楼主| 一路向北lm 发表于 2018-11-12 20:37 | 显示全部楼层
wsnsyy 发表于 2018-11-13 13:12 | 显示全部楼层
mark,用什么单片机做的啊
山东电子小菜鸟 发表于 2018-11-13 16:14 来自手机 | 显示全部楼层
学到opencv了吗
 楼主| 一路向北lm 发表于 2018-11-15 11:26 | 显示全部楼层
 楼主| 一路向北lm 发表于 2018-11-20 16:02 | 显示全部楼层
wsnsyy 发表于 2018-11-13 13:12
mark,用什么单片机做的啊

单片机就有点难了
 楼主| 一路向北lm 发表于 2018-11-20 16:04 | 显示全部楼层
图像混合

5.1 线性混合操作—理论
5.2  OpenCV api函数
addWeightted ( 参数1:输入图像1;    参数2:输入图像1alpha值;
              参数3:输入图像2;  参数4:输入图像2alpha值;
              参数4gamma的值(校验值); 参数6:输出的混合图像;
            )
主:两张图片的大小和类型一致。
Saturate(t) :确保t 0-255之间。
  1. // 两张同大小类型的图片混合
  2. int image_blend()
  3. {
  4.         Mat src1,src2,dst;
  5.         src1 = imread("1.png");
  6.         src2 =imread("2.png");
  7.         if(src1.empty())
  8.         {
  9.           printf("不能载入图像1.png\r\n");
  10.           return -1;
  11.         }
  12.         if(src2.empty())
  13.         {
  14.           printf("不能载入图像2.png\r\n");
  15.           return -1;
  16.         }
  17.         double alpha = 0.5;
  18.         if(src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type())
  19.         {
  20.                 addWeighted(src1,alpha,src2,1-alpha,0.0,dst);
  21.                 imshow("src1 image",src1);
  22.                 imshow("src2 image",src2);
  23.                 imshow("blend image",dst);
  24.         }
  25.         else
  26.         {
  27.             printf("两张图片大大小尺寸不一致\r\n");
  28.         }
  29.         waitKey(0);
  30. }



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 一路向北lm 发表于 2018-11-20 16:05 | 显示全部楼层

图像亮度与对比度调节


图像的亮度与对比度调节原理
  1. int image_change_bright()
  2. {
  3.    Mat src,dst;
  4.    src = imread("E:\\1.png");
  5.    if(src.empty())
  6.    {
  7.       printf("打开图像失败\n");
  8.           return -1;
  9.    }
  10.    imshow("input image",src);

  11.    int height =src.rows;
  12.    int wide =src.cols;
  13.    dst = Mat::zeros(src.size(),src.type());
  14.    int alpha = 1.5;
  15.    int bate =50;
  16.    for(int row=0;row<height;row++)
  17.            for(int col=0;col<wide;col++)
  18.            {
  19.                    if(src.channels()==3)
  20.                    {
  21.                            int b= src.at<Vec3b>(row,col)[0];
  22.                            int g= src.at<Vec3b>(row,col)[1];
  23.                            int r= src.at<Vec3b>(row,col)[2];

  24.                            dst.at<Vec3b>(row,col)[0]=saturate_cast<uchar>(b*alpha+bate);
  25.                            dst.at<Vec3b>(row,col)[1]=saturate_cast<uchar>(g*alpha+bate);
  26.                            dst.at<Vec3b>(row,col)[2]=saturate_cast<uchar>(r*alpha+bate);
  27.                    }
  28.                   
  29.            }
  30.            imshow("output",dst);
  31.            waitKey(0);
  32. }



 楼主| 一路向北lm 发表于 2018-11-20 16:08 | 显示全部楼层
绘制形状与文字
7.1 绘制直线
  1.   /* 画线 */
  2.         Point p1 = (20, 30);
  3.         Point p2;
  4.         p2.x = 300;
  5.         p2.y = 300;
  6.         Scalar color = Scalar(0, 0, 255);
  7.         line(src, p1, p2, color, 3, LINE_8);
7.2 绘制矩形
  1. /* 画矩形 */
  2.         Rect rect = Rect(200, 100, 300, 300);
  3.         Scalar color = Scalar(255, 0, 0);
  4.         rectangle(src, rect, color, 2, LINE_8);
7.3 绘制椭圆
  1. /* 绘制椭圆 */
  2.           Scalar color = Scalar(0, 255, 0);
  3.         ellipse(src, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 4), 90,0, 360, color, 2, LINE_4);


 楼主| 一路向北lm 发表于 2018-11-20 16:10 | 显示全部楼层
绘制圆
  1. /* 绘制圆 */       
  2.         Scalar color = Scalar(255, 0, 255);
  3.         Point center = Point(src.cols / 2, src.rows / 2);
  4. circle(src, center, 150, color, 1, 8);
绘制文字
  1. Mat src;
  2.         src = imread("E:/1.png");   putText(src,"hellowopenCV",Point(10,100),CV_FONT_HERSHEY_COMPLEX,1.0,Scalar(12,23,200),3,8);
  3.          imshow("output image",src);
  4.          waitKey(0);
绘制随机直线
  1. Mat src;
  2.         src = imread("E:/1.png");
  3.         RNG rng(12345);
  4.         Point p1;
  5.         Point p2;
  6.         Mat bg = Mat::zeros(src.size(), src.type());
  7.         while (1)
  8.         {
  9.                 for (int i = 0; i < 10000; i++)
  10.                 {
  11.                         p1.x = rng.uniform(0, src.cols);
  12.                         p1.y = rng.uniform(0, src.rows);
  13.         p2.x = rng.uniform(0, src.cols);
  14.         p2.y = rng.uniform(0, src.rows);
  15.         Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
  16.         line(bg, p1, p2, color, 1, 8);
  17.         imshow("input", bg);
  18.         if (waitKey(50) > 0)
  19.         {
  20.         break;
  21.         }
  22. }
  23. }
效果图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部