打印
[程序源码]

OpenCV 图像的简单处理

[复制链接]
2513|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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 格式的时候可以保存透明通道的图片, 可以指定压缩参数。
参考代码:
/* 基本操作, 加载图像 修改图像, 显示图像, 保存图像 */
int image_open_save()
{
Mat src=imread("E:\\1.png"); // 载入图片
if(!src.data)
{
printf("不能加载图片\r\n");
return -1;
} n
amedWindow("test1",CV_WINDOW_AUTOSIZE); // 新建窗口
imshow("test1",src); // 显示图像
namedWindow("test2"); // 新建窗口
Mat out_image;
cvtColor(src,out_image,COLOR_BGR2GRAY); //图像转换
imshow("test2",out_image); // 显示图像
imwrite("E:\\01.jpg",out_image); // 保存图像
waitKey(0);
}  


相关帖子

沙发
一路向北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 等。

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



使用特权

评论回复
板凳
一路向北lm|  楼主 | 2018-11-11 13:27 | 只看该作者
3.Mat 对象的使用  

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

  


使用特权

评论回复
地板
一路向北lm|  楼主 | 2018-11-11 13:29 | 只看该作者
4.图像操作  

4.1 读写单通道像素, 修改单通道像素
参考代码:
// 读取单通道像素 , 修改
Mat dst;
cvtColor(src,dst,CV_BGR2GRAY);
imshow("gray",dst);
int width = dst.cols;
int height = dst.rows;
for(int col=0;col<width;col++)
for(int row=0;row<height;row++)
{
int gray=dst.at<uchar>(row,col);
dst.at<uchar>(row,col) = 255-gray;
}
imshow("grayto",dst);
4.2 读写多通道像素, 修改单通道像素
参考代码
Mat dst;
dst.create(src.size(),src.type());
int width = src.cols;
int height = src.rows;
int nc = src.channels();
for(int col=0;col<width;col++)
for(int row=0;row<height;row++)
{
if(nc==1)
{
int gray=src.at<uchar>(row,col);
src.at<uchar>(row,col) = 255-gray;
}
else if(nc==3)
{
int b =src.at<Vec3b>(row,col)[0];
int g =src.at<Vec3b>(row,col)[1];
int r =src.at<Vec3b>(row,col)[2];
dst.at<Vec3b>(row,col)[0]=255-b;
dst.at<Vec3b>(row,col)[1]=255-g;
dst.at<Vec3b>(row,col)[2]=255-r;
}
}
imshow("grayto",dst);


使用特权

评论回复
5
caijie001| | 2018-11-12 14:12 | 只看该作者

使用特权

评论回复
6
一路向北lm|  楼主 | 2018-11-12 20:37 | 只看该作者

使用特权

评论回复
7
一路向北lm|  楼主 | 2018-11-12 20:37 | 只看该作者

使用特权

评论回复
8
wsnsyy| | 2018-11-13 13:12 | 只看该作者
mark,用什么单片机做的啊

使用特权

评论回复
9
山东电子小菜鸟| | 2018-11-13 16:14 | 只看该作者
学到opencv了吗

使用特权

评论回复
10
一路向北lm|  楼主 | 2018-11-15 11:26 | 只看该作者

使用特权

评论回复
11
一路向北lm|  楼主 | 2018-11-20 16:02 | 只看该作者
wsnsyy 发表于 2018-11-13 13:12
mark,用什么单片机做的啊

单片机就有点难了

使用特权

评论回复
12
一路向北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之间。
// 两张同大小类型的图片混合
int image_blend()
{
        Mat src1,src2,dst;
        src1 = imread("1.png");
        src2 =imread("2.png");
        if(src1.empty())
        {
          printf("不能载入图像1.png\r\n");
          return -1;
        }
        if(src2.empty())
        {
          printf("不能载入图像2.png\r\n");
          return -1;
        }
        double alpha = 0.5;
        if(src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type())
        {
                addWeighted(src1,alpha,src2,1-alpha,0.0,dst);
                imshow("src1 image",src1);
                imshow("src2 image",src2);
                imshow("blend image",dst);
        }
        else
        {
            printf("两张图片大大小尺寸不一致\r\n");
        }
        waitKey(0);
}



使用特权

评论回复
13
一路向北lm|  楼主 | 2018-11-20 16:05 | 只看该作者

图像亮度与对比度调节


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

   int height =src.rows;
   int wide =src.cols;
   dst = Mat::zeros(src.size(),src.type());
   int alpha = 1.5;
   int bate =50;
   for(int row=0;row<height;row++)
           for(int col=0;col<wide;col++)
           {
                   if(src.channels()==3)
                   {
                           int b= src.at<Vec3b>(row,col)[0];
                           int g= src.at<Vec3b>(row,col)[1];
                           int r= src.at<Vec3b>(row,col)[2];

                           dst.at<Vec3b>(row,col)[0]=saturate_cast<uchar>(b*alpha+bate);
                           dst.at<Vec3b>(row,col)[1]=saturate_cast<uchar>(g*alpha+bate);
                           dst.at<Vec3b>(row,col)[2]=saturate_cast<uchar>(r*alpha+bate);
                   }
                  
           }
           imshow("output",dst);
           waitKey(0);
}



使用特权

评论回复
14
一路向北lm|  楼主 | 2018-11-20 16:08 | 只看该作者
绘制形状与文字
7.1 绘制直线
  /* 画线 */
        Point p1 = (20, 30);
        Point p2;
        p2.x = 300;
        p2.y = 300;
        Scalar color = Scalar(0, 0, 255);
        line(src, p1, p2, color, 3, LINE_8);
7.2 绘制矩形
/* 画矩形 */
        Rect rect = Rect(200, 100, 300, 300);
        Scalar color = Scalar(255, 0, 0);
        rectangle(src, rect, color, 2, LINE_8);
7.3 绘制椭圆
/* 绘制椭圆 */
          Scalar color = Scalar(0, 255, 0);
        ellipse(src, Point(src.cols / 2, src.rows / 2), Size(src.cols / 4, src.rows / 4), 90,0, 360, color, 2, LINE_4);


使用特权

评论回复
15
一路向北lm|  楼主 | 2018-11-20 16:10 | 只看该作者
绘制圆
 /* 绘制圆 */        
        Scalar color = Scalar(255, 0, 255);
        Point center = Point(src.cols / 2, src.rows / 2);
circle(src, center, 150, color, 1, 8);
绘制文字
Mat src;
        src = imread("E:/1.png");   putText(src,"hellowopenCV",Point(10,100),CV_FONT_HERSHEY_COMPLEX,1.0,Scalar(12,23,200),3,8);
         imshow("output image",src);
         waitKey(0);
绘制随机直线
 Mat src;
        src = imread("E:/1.png");
        RNG rng(12345);
        Point p1;
        Point p2;
        Mat bg = Mat::zeros(src.size(), src.type());
        while (1)
        {
                for (int i = 0; i < 10000; i++)
                {
                        p1.x = rng.uniform(0, src.cols);
                        p1.y = rng.uniform(0, src.rows);
        p2.x = rng.uniform(0, src.cols);
        p2.y = rng.uniform(0, src.rows);
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        line(bg, p1, p2, color, 1, 8);
        imshow("input", bg);
        if (waitKey(50) > 0)
        {
        break;
        }
}
}
效果图:

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

274

主题

3760

帖子

75

粉丝