我有原始图片:
然后我阅读它,创建一个PSF,并在Matlab中对其进行模糊处理:
lenawords1=imread('lenawords.bmp');
%create PSF
sigma=6;
PSFgauss=fspecial('gaussian', 8*sigma+1, sigma);
%blur it
lenablur1=imfilter(lenawords1, PSFgauss, 'conv');
lenablurgray1=mat2gray(lenablur1);
PSFgaussgray = mat2gray(PSFgauss);
我保存了模糊的图像:
imwrite(lenablurgray1, 'lenablur.bmp');
当我在其中显示一些值时,我得到
disp(lenablurgray1(91:93, 71:75))
0.5556 0.5778 0.6000 0.6222 0.6444
0.6000 0.6444 0.6667 0.6889 0.6889
0.6444 0.6889 0.7111 0.7333 0.7333
然后我在OpenCV中打开该模糊图像,并在相同的索引处显示其值:
Mat img = imread("lenablur.bmp");
for (int r = 91; r < 94; r++) {
for (int c = 71; c < 76; c++) {
cout << img.at<double>(r, c) << " ";
}
cout << endl;
}
cout << endl;
我得到的结果与上面的值不匹配:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
这是为什么?
编辑:img.at<unsigned int>(r, c)
给出
1903260029 1533437542 ...
2004318088 ...
....
如果我将模糊图像另存为png文件:
imwrite(lenablurgray1, 'lenablur.png');
然后在OpenCV中阅读它:
Mat img = imread("lenablur.png");
img.convertTo(img, CV_64F);
然后img.at<double>(r, c)
给出
17 11 11 11 6
17 11 11 11 6
17 11 11 11 11
仍然与Matlab中的值不匹配
EDIT2 :我现在看到该值对于内核是错误的。在Matlab中,我得到了
imwrite(PSFgaussgray, 'PSFgauss.bmp');
disp(PSFgaussgray(7:9, 7:9)*256)
.0316 .0513 .0812
.0513 ...
...
而在OpenCV中:
Mat kernel = imread("PSFgauss.bmp");
cvtColor(kernel, kernel, cv::COLOR_BGR2GRAY);
kernel.convertTo(kernel, CV_64F);
for (int r = 6; r < 9 ; r++) {
for (int c = 6; c < 9; c++) {
cout << kernel.at<double>(r, c) << " ";
}
cout << endl;
}
cout << endl;
我得到的结果与上面的值不匹配:
0 0 0
0 0 0
0 0 0
答案 0 :(得分:6)
要了解您所看到的差异,您需要了解MATLAB如何将图像保存到BMP或PNG文件中,以及OpenCV如何读取它。
在这种情况下,MATLAB假设图像的类型为double
,其强度范围为[0,1]。也就是说,不希望像素值低于0且高于1。保存到文件中后,将此类图像乘以255并转换为8位整数(范围为[0,255])。
因此,如果
>> disp(lenablurgray1(91:93, 71:75))
0.5556 0.5778 0.6000 0.6222 0.6444
0.6000 0.6444 0.6667 0.6889 0.6889
0.6444 0.6889 0.7111 0.7333 0.7333
保存的是
>> uint8( lenablurgray1(91:93, 71:75) * 255 )
142 147 153 159 164
153 164 170 176 176
164 176 181 187 187
接下来,OpenCV将以RGB(或更确切地说,BGR,OpenCV的尴尬颜色顺序)和8位无符号整数(CV_8U
)读取此文件。要显示这些数据,请提取颜色通道之一,或使用
cvtColor(img, img, cv::COLOR_BGR2GRAY);
然后,使用读取8位无符号值
img.at<uchar>(r, c)
如果您用img.at<double>()
读取它们,则每8个连续像素的组将被视为一个像素值(double
有8个字节)。
接下来,请记住,MATLAB的索引从1开始,而OpenCV的索引从0开始。因此您的循环应如下所示:
for (int r = 90; r < 93; r++) { // matches MATLAB's 91:93 indexing
for (int c = 70; c < 75; c++) { // matches MATLAB's 71:75 indexing
cout << (int)img.at<uchar>(r, c) << " ";
}
cout << '\n';
}
cout << '\n';
最后,对于您的内核,请注意,将其值乘以255仍远小于单位:.0316 .0513 .0812
。这些值将被写入0到BMP或PNG文件中。如果要保存这些值,则需要缩放内核,使其最大值为1:
PSFgauss = PSFgauss / max(PSFgauss(:));
imwrite(PSFgauss, 'PSFgauss.bmp');
(请注意,此内核已经是灰度图像,您无需在其上使用mat2gray
。)