use*_*619 2 matlab opencv image image-processing
我有一张原始图片:
我然后阅读它,创建一个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);
Run Code Online (Sandbox Code Playgroud)
我保存了模糊的图像:
imwrite(lenablurgray1, 'lenablur.bmp');
Run Code Online (Sandbox Code Playgroud)
当我在其中显示一些值时,我得到了
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
Run Code Online (Sandbox Code Playgroud)
然后,我在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;
Run Code Online (Sandbox Code Playgroud)
我得到的结果与上面的值不匹配:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
编辑: img.at<unsigned int>(r, c)
给
1903260029 1533437542 ...
2004318088 ...
....
Run Code Online (Sandbox Code Playgroud)
如果我将模糊图像保存为png文件:
imwrite(lenablurgray1, 'lenablur.png');
Run Code Online (Sandbox Code Playgroud)
然后当我在OpenCV中阅读它时:
Mat img = imread("lenablur.png");
img.convertTo(img, CV_64F);
Run Code Online (Sandbox Code Playgroud)
然后img.at<double>(r, c)
给
17 11 11 11 6
17 11 11 11 6
17 11 11 11 11
Run Code Online (Sandbox Code Playgroud)
它仍然与Matlab的值不匹配
EDIT2:我现在看到内核的值是错误的.在Matlab中,我得到了
imwrite(PSFgaussgray, 'PSFgauss.bmp');
disp(PSFgaussgray(7:9, 7:9)*256)
.0316 .0513 .0812
.0513 ...
...
Run Code Online (Sandbox Code Playgroud)
而在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;
Run Code Online (Sandbox Code Playgroud)
我得到的结果与上面的值不匹配:
0 0 0
0 0 0
0 0 0
Run Code Online (Sandbox Code Playgroud)
要了解这种差异,您需要了解MATLAB如何将图像保存到BMP或PNG文件,以及OpenCV如何读取它.
如果图像的类型double
是这种情况,MATLAB假设它的强度范围是[0,1].也就是说,不期望低于0和高于1的像素值.这样的图像被乘以255,并转换成8位整数(其具有一定范围的[0255]),当保存到文件中.
因此,如果
>> 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
Run Code Online (Sandbox Code Playgroud)
节省的是
>> uint8( lenablurgray1(91:93, 71:75) * 255 )
142 147 153 159 164
153 164 170 176 176
164 176 181 187 187
Run Code Online (Sandbox Code Playgroud)
接下来,OpenCV将此文件读取为RGB(或更确切地说是BGR,OpenCV的笨拙颜色顺序)和8位无符号整数(CV_8U
).要显示这些数据,请提取其中一个颜色通道,或使用转换为灰度值
cvtColor(img, img, cv::COLOR_BGR2GRAY);
Run Code Online (Sandbox Code Playgroud)
然后,使用读取8位无符号值
img.at<uchar>(r, c)
Run Code Online (Sandbox Code Playgroud)
如果你用它们读取它们img.at<double>()
,8个连续像素的组将被视为单个像素值(a 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';
Run Code Online (Sandbox Code Playgroud)
最后,就你的内核而言,请注意,当乘以255时,它的值仍远小于1 : .0316 .0513 .0812
. 这些值将写为0到BMP或PNG文件.如果要保存这些值,则需要缩放内核,使其最大值为1:
PSFgauss = PSFgauss / max(PSFgauss(:));
imwrite(PSFgauss, 'PSFgauss.bmp');
Run Code Online (Sandbox Code Playgroud)
(请注意,此内核已经是灰度值图像,您无需mat2gray
在其上使用.)