当前位置:C++技术网 > 资讯 > opencv编程:19 两张图像进行叠加(三)

opencv编程:19 两张图像进行叠加(三)

更新时间:2016-08-07 23:22:37浏览次数:1+次

  上一篇文章中介绍了使用copyTo()函数将lena图像中的感兴趣区域替换为logo图像,而copyto()函数有一个重载函数可以实现只替换logo图标而忽略图标的背景。

C++: void Mat::copyTo(OutputArray m, InputArray mask) const
Parameters
m – Destination matrix. If it does not have a proper size or type before the operation, it isreallocated.
mask –Operation mask. Its non-zero elements indicate which matrix elements need to be copied.
  函数的功能仍然是实现矩阵的拷贝,m是输出矩阵,mask是读取的logo图像的灰度模式。由描述可知,copyTo函数的这种形式只会用mask中非零元素去替换m中的相应位置,这就是说如果我们希望只叠加logo图标而不要背景,那背景就要求为黑色的。

 这里不使用opencv图标了,使用我最喜欢的游戏的logo,叠加位置依然是左上角。先展示下图像,Lena 和 logo

       

                             

示例代码1,
Mat image=imread("lena.png");  //读取背景图像
Mat logo = imread("logo-Assassin's.jpg");  //读取logo图像
Mat mask = imread("logo-Assassin's.jpg",0);  //读取logo图像并将图像转换成灰度
Mat imageROI=image(Rect(0,0,mask.cols,mask.rows));   //获取感兴趣区域
logo.copyTo(imageROI,mask);
namedWindow("叠加");      //显示叠加图像
imshow("叠加",image);
waitKey(0);
叠加结果,

             

  可以看出叠加情况并不是预想的结果。可以看出,logo图像是一小部分黑色背景被去掉了,而图标部分完完整整的都在。既然黑色背景一部分能被去除,说明思路是没问题的,对logo图像进行分析查看,发现logo图像的背景是“有问题”的,黑色背景不是“纯黑”,所以要对logo图像进行点处理。

示例代码2,
Mat image=imread("lena.png");  //读取背景图像
Mat logo = imread("logo-Assassin's.jpg");  //读取logo图像
Mat mask = imread("logo-Assassin's.jpg",0);  //读取logo图像并将图像转换成灰度
threshold(mask,mask,40,255,CV_THRESH_BINARY);   //对图像进行二值化处理
Mat imageROI=image(Rect(0,0,mask.cols,mask.rows));   //获取感兴趣区域
logo.copyTo(imageROI,mask);
namedWindow("叠加");      //显示叠加图像
imshow("叠加",image);
waitKey(0);
 在原先代码的基础上加了一句对mask进行处理的代码,对mask灰度图进行二值化,结果果然如预期的一样。因为logo图像正好是只有黑白两种颜色,所以可以通过二值化操作让黑色变“纯黑”,白色变“纯白”。

 叠加效果如下,