先上一段有关opencv的代码。
bool Image_Split()
{
vector<Mat> channels;
Mat srcImage = imread(IMAGE);
Mat logo = imread(LOGO);
Mat Blue_channel;
//判断采集到的srcImage和logo图像是否为0
if(!srcImage.data)
{
cout << "加载原图片失败!"<< endl;
return false ;
}
if(!logo.data)
{
cout << "加载logo图片失败!" << endl;
return false ;
}
//从srcImage中分离三通道(实质为分成三个向量,即数组)
split(srcImage,channels);
//取该通道的颜色为蓝色
Blue_channel = channels.at(0);
//把分离的通道的图片取自己感兴趣的一部分,即是Rect(),把logo图案与之按照一定权重贴在Rect()部分上
addWeighted(Blue_channel(Rect(0,583,logo.cols , logo.rows)), 0.5 ,logo, 0.5,
0.0, Blue_channel(Rect(0 ,583 ,logo.cols, logo.rows)));
//最后把单色调的三种图片归并为三通道图片
merge(channels,srcImage);
namedWindow("测试图.jpg");
imshow("测试图.jpg",srcImage);
return true;
}
这段代码看似没问题,逻辑上也是合情合理,而且编译也通过,然而并不能执行。
一旦执行就会出现Error - RtlWerpReportException failed with status code :-1073741823这个问题。那么,如何解决这个问题呢?很简单,在定义logo 的时候,让Mat logo = imread(LOGO, 0);
取0是什么意思呢?在imread函数中,0即是CV_LOAD_IMAGE_GRAYSCALE
CV_LOAD_IMAGE_GRAYSCALE- 如果取这个标识的话,始终将图像转换成灰度1
那为甚么这样就没错了?因为,这其实就是一个内存引发的问题。我们知道,如果imread采样图片使之未默认值,即是1,此时便是CV_LOAD_IMAGE_COLOR
CV_LOAD_IMAGE_COLOR- 如果取这个标识的话,总是转换图像到彩色一体
这个图片为3通道,存储方式为0xFF FF FF(设最大),如果我们srcImage采集的图片是默认,那么此时应该为0xFF FF FF(设最大),如果我们使用split()函数,此时Blue_channel得到的应该为单通道的数组,范围在0~255之间,即是0x00~0xFF,此时如果我们采集的logo图片为三通道图片,即是imread默认为1,执行addWeighted()函数的时候,就要把三通道的logo图片(大小为0~0xFF FF FF)与单通道图片Blue_channel(范围在0~0xFF)加权叠加,而后赋值于Blue_channel,此时必定会发生溢出,内存报错。(logo的大小大于Blue_channel)
所以我们可以认为Error - RtlWerpReportException failed with status code :-1073741823,这个就是内存问题,也就是Linux下老生常谈的“段错误”。