在这里,首先对Fred_Yang2013表示衷心的感谢,是他的博客给了我很大的提示,还有坛友xjtuzhw的无私帮助亦表示感谢。
本人opencv入门,写了一个给图像文件加噪声的子函数salt.cpp,然后再主函数main中调用,用以显示原图像文件和加噪声文件之间的明显对比。但是现在出现了一个问题,如果我先调用salt()函数,然后imshow()显示原图和加噪之后的图片,会发现显示的两幅图片均是加噪后的结果,原图片被修改了。但是我若是先imshow原图片,然后加噪声salt(),此时再用imshow()加噪的图片,才是我想要的结果。其实这对程序本身没什么影响,但是我想知道怎样才能达到如下目的:先调用salt(),然后imshow()原图片和加噪图片,使得原始图像和加噪图像均能正常地显示?(原始图像和加噪图像能正常的对比显示?)
语言叙述不是很清晰:具体代码请大家过目先是加噪的子函数salt(),独立存储为salt.cpp
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; void salt(cv::Mat &image,cv::Mat &resultimg,int n){ resultimg=image; for(int k=0;k<n;k++){ int i=rand()%resultimg.cols; int j=rand()%resultimg.rows; if(resultimg.channels()==1){//graylevel image resultimg.at<uchar>(j,i)=255; }else if(resultimg.channels()==3){//color image resultimg.at<cv::Vec3b>(j,i)[0]=255; resultimg.at<cv::Vec3b>(j,i)[1]=255; resultimg.at<cv::Vec3b>(j,i)[2]=255; } } }
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; //隐藏控制台窗口 #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //调用salt.cpp中子函数的方法 void salt(cv::Mat &image,cv::Mat &resultimg,int n); int main() { const char *pstrImageName = "lena.jpg"; const char *pstrSaveImageName = "lena_resize.jpg"; const char *pstrWindowsSrcTitle = "原图 "; const char *pstrWindowsDstTitle = "缩放图"; //初始化图像对象 cv::Mat image=cv::imread(pstrImageName); cv::Mat resultimg ; cv::namedWindow(pstrWindowsSrcTitle); cv::namedWindow(pstrWindowsDstTitle); salt(image,resultimg,3000); cv::imshow("original",image); cv::imshow("salt result",resultimg); cv::waitKey(0); return 1; }
后来 经过自己的摸索 发现
原来opencv中的Mat类使用引用计数,当图像赋值给另一个变量时,不用复制,只是将之指向相同的内存块,引用计数加一。当所有对图像引用取消时,内存才被释放,且只释放一次。因而普通的赋值操作“=”实质上是共享同一块内存空间,此时产生的操作会对所有的"="关联的变量起作用。如果要实现真正的独享操作,opencv提供了copyto()来实现。因而salt()代码更改如下:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; void salt(cv::Mat &image,cv::Mat &resultimg,int n){ image.copyto(resultimg); for(int k=0;k<n;k++){ int i=rand()%resultimg.cols; int j=rand()%resultimg.rows; if(resultimg.channels()==1){//graylevel image resultimg.at<uchar>(j,i)=255; }else if(resultimg.channels()==3){//color image resultimg.at<cv::Vec3b>(j,i)[0]=255; resultimg.at<cv::Vec3b>(j,i)[1]=255; resultimg.at<cv::Vec3b>(j,i)[2]=255; } } }此时结果为理想状态
原文:http://blog.csdn.net/liu6tot/article/details/20123115