我尝试在c ++中实现侵蚀(形态学操作),我使用OpenCV进行读取并显示侵蚀后的第一张图像和图像。
我想逐步解释我的做法:
我的面具如:
[255 255 255
255 255 255
255 255 255]
这是我的代码:
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
#define WIDTH 16
#define HEIGHT 16
int main( int argc, char** argv )
{
Mat image(HEIGHT, WIDTH, CV_8UC1);
Mat imageFinal(HEIGHT, WIDTH, CV_8UC1);
int values[WIDTH][HEIGHT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int row = 0; row < WIDTH; row++){
for(int col = 0; col < HEIGHT; col++){
image.data[col + row * image.cols] = values[row][col];
}
}
image.copyTo(imageFinal);
int count = 0;
for(int row = 1; row < image.rows-1; row++){
for(int col = 1; col < image.cols-1; col++){
count = 0;
for(int a = -1; a <= 1; a++){
for(int b = -1; b <= 1; b++){
if(image.at<uchar>(row + a, col + b) == 255){
count++;
}
}
}cout << count << endl;
if(count == 9){
for(int a = -1; a <= 1; a++){
for(int b = -1; b <= 1; b++){
if(a != 0 && b != 0){
imageFinal.at<uchar>(row + a, col + b) = 0;
}
}
}
}
}
}
imshow("Image", image);
imshow("final", imageFinal);
waitKey(0);
return 0;
}
但结果却不正确。
Initial image and correct result: [错误的结果] [1]
答案 0 :(得分:1)
我不是百分百肯定,但在阅读wiki entry on erosion后,我认为正确的实施将是这样的:
for each pixel(x,y) in original_image
count neigbours where original_image == 255
if count == 9
new_image(x,y) = 255
else
new_image(x,y) = 0
end
end
,而你有
for each pixel(x,y) in original_image
count neigbours where original_image == 255
if count == 9
set all neighbours (but not the pixel itself) in new_image to 0
end
基本上侵蚀应该对图像的3x3部分进行...
1 1 1 ? ? ? 0 1 1 ? ? ?
1 1 1 -> ? 1 ? and 1 1 1 -> ? 0 ?
1 1 1 ? ? ? 1 1 1 ? ? ?
但你做了
1 1 1 0 0 0
1 1 1 -> 0 1 0
1 1 1 0 0 0
应用滤镜时,您应该只更改正在查看的像素的值,但更改所有邻居,而不是像素本身。
我发现维基文章中的公式不太具启发性,也许这有助于理解:
new_image(x,y) = (3x3Sub(old_image,x,y) == mask) * 255