用了两种访问数据的方法。一种是用cv::LUT查表的方法遍历进行变换。一种是用迭代器进行遍历变换。对于单通道的灰度图像,两种方法输出的结果图像相同。但是对于3通道彩色图像,两种方法得到的图像不同,问题是出在了split和merge这个操作与直接遍历变换 两个不同操作导致的结果不同吗???????
cv::Mat gammatrans(cv::Mat &srcImg,float gamma)
{
cv::Mat LUT(1,256,CV_8UC1);
for(int i=0;i<256;i++)
{
LUT.at<uchar>(0,i)=cv::saturate_cast<uchar>(pow((float)(i/255.0f),gamma)*255.0f);
}
cv::Mat resultImg=srcImg.clone();
if(srcImg.channels()==1)
{
cv::LUT(srcImg,LUT,resultImg);
}
else
{
std::vector<cv::Mat> vec;
cv::split(srcImg,vec);
cv::LUT(vec[0],LUT,vec[0]);
cv::LUT(vec[1],LUT,vec[1]);
cv::LUT(vec[1],LUT,vec[1]);
cv::merge(vec,resultImg);
}
return resultImg;
}
cv::Mat gammatrans2(cv::Mat &srcImg,float gamma)
{
uchar LUT[256];
for(int i=0;i<256;i++)
{
LUT[i]=cv::saturate_cast<uchar>(pow((float)(i/255.0f),gamma)*255.0f);
}
cv::Mat resultImg=srcImg.clone();
if(srcImg.channels()==1)
{
cv::MatIterator_<uchar>iterator=resultImg.begin<uchar>();
cv::MatIterator_<uchar>iteratorEnd=resultImg.end<uchar>();
for(;iterator!=iteratorEnd;iterator++)
*iterator=LUT[(*iterator)];
}
else
{
cv::MatIterator_<cv::Vec3b>iterator=resultImg.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b>iteratorEnd=resultImg.end<cv::Vec3b>();
for(;iterator!=iteratorEnd;iterator++)
{
(*iterator)[0]=LUT[((*iterator)[0])];
(*iterator)[1]=LUT[((*iterator)[1])];
(*iterator)[2]=LUT[((*iterator)[2])];
}
}
return resultImg;
}
int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat srcImg=cv::imread("C:\\Users\\mona\\Desktop\\新建文件夹\\倩女幽魂.jpg");
float gamma1=0.45;
float gamma2=2.2;
cv::Mat result1=gammatrans(srcImg,gamma1);
cv::Mat result2=gammatrans(srcImg,gamma2);
cv::Mat result3=gammatrans2(srcImg,gamma1);
cv::Mat result4=gammatrans2(srcImg,gamma2);
cv::imshow("原图",srcImg);
cv::imshow("0.45gamma", result1);
cv::imshow("2.2gamma", result2);
cv::imshow("0.45gamma2", result3);
cv::imshow("2.2gamma2", result4);
cv::waitKey(0);
return 0;
}
split和merge方法得到的图像
迭代器方法得到的图像
结果明显不同!
究竟是为什么呢??????????