OpenCV 学习(图像的基本运算)

OpenCV 学习(图像的基本运算)

图像的基本运算有很多种,比如两幅图像可以相加、相减、甚至可以相乘、相除。图像可以放大、缩小、旋转,还可以截取中间的一副子图,各个颜色通道还可以分别提取。总之,对于图像可以进行的基本运算非常的多,这里不可能全部都写出来,只是挑了些特别常用的简单的写写。

图像间的加减乘除

OpenCV 中提供了如下的一些函数,用来进行图像的加减乘除。

void add(InputArray src1, InputArray src2, OutputArray dst,
                  InputArray mask=noArray(), int dtype=-1);

void subtract(InputArray src1, InputArray src2, OutputArray dst,
                       InputArray mask=noArray(), int dtype=-1);

void multiply(InputArray src1, InputArray src2,
                       OutputArray dst, double scale=1, int dtype=-1);

void divide(InputArray src1, InputArray src2, OutputArray dst,
                     double scale=1, int dtype=-1);

void divide(double scale, InputArray src2,
                     OutputArray dst, int dtype=-1);

void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);

void addWeighted(InputArray src1, double alpha, InputArray src2,
                          double beta, double gamma, OutputArray dst, int dtype=-1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这些函数都要求相加的两幅图像具有相同的尺寸,并且像素类型是相同的。

比如我们有两幅尺寸相同的图像,分别如下:

这里写图片描述 
这里写图片描述

执行下面的操作后:

cv::addWeighted(image, 0.5, image2, 0.5, 0., result);
  • 1
  • 2

得到的输出图像如下:

这里写图片描述

实际上,上面的代码还可以写为:

result= 0.5 * image1 + 0.5 * image2;
  • 1
  • 2

与此类似的还有位运算函数:

void bitwise_and(InputArray src1, InputArray src2,
                          OutputArray dst, InputArray mask=noArray());

void bitwise_or(InputArray src1, InputArray src2,
                         OutputArray dst, InputArray mask=noArray());

void bitwise_xor(InputArray src1, InputArray src2,
                          OutputArray dst, InputArray mask=noArray());

void bitwise_not(InputArray src, OutputArray dst,
                          InputArray mask=noArray());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

用法很简单,就不多介绍了。

另外一个比较常用的运算是求两幅图像像素的差的绝对值。

void absdiff(InputArray src1, InputArray src2, OutputArray dst);
  • 1
  • 2

还有些函数是对单幅图像进行操作的,比如对每个像素的值取平方、平方根、对数等。

void sqrt(InputArray src, OutputArray dst);
void pow(InputArray src, double power, OutputArray dst);
void exp(InputArray src, OutputArray dst);
void log(InputArray src, OutputArray dst);
  • 1
  • 2
  • 3
  • 4
  • 5

这里给出的函数很有限。但是,基本上我们能想到的各种操作,OpenCV 的作者都替我们实现了,需要时可以现查。

上面的操作都假定两幅图像是相同大小的。当图像大小不同时,我们可以在较大的图像中挖取出一块小区域。

取图像中的子区域(ROI)

下面的代码在一副图像中加入个 logo。 logo 图像如下: 
这里写图片描述

cv::Mat imageROI;
imageROI= image(cv::Rect(385,270,logo.cols, logo.rows));
// add logo to image
cv::addWeighted(imageROI, 1.0, logo,  0.3,0., imageROI);
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述

如果我们的 ROI 由图像中的一些连续行或连续列组成。可以用下面的方式来定义:

cv::Mat imageROI= image.rowRange(start,end);
cv::Mat imageROI= image.colRange(start,end) ;
  • 1
  • 2
  • 3

分离图像的通道

有时,我们需要单独处理图像的某一个通道,这时可以可以用 split函数来分离图像的通道。

void split(const Mat& src, vector<Mat_<_Tp> >& mv);
  • 1
  • 2

这个函数将一副图像的各个通道,分离成多个矩阵。

std::vector<cv::Mat> planes;
cv::split(image1, planes);
  • 1
  • 2
  • 3

对某个通道处理完成后,可以用 merge 函数组合回彩色图像。

void merge(const vector<Mat>& mv, OutputArray dst );

猜你喜欢

转载自blog.csdn.net/xiachong27/article/details/80464849