二值图像的腐蚀和膨胀就是将一个结构元素(小型二值图,一般为3*3大小)在一个大的二值图上逐点移动并进行比较,根据比较的结果作出相应处理而已。本程序将骨架默认为白色。
腐蚀:结构元素的白点与要处理的图形对应像素点全部相同,则该点为白色,否则变为黑色(即被腐蚀掉了);
膨胀:结构元素的白点与要处理的图形对应像素点只要有一个相同,则该点设为白色,否则仍然为黑色。
对二值图像来说,白色被腐蚀即为黑色的膨胀,白色的膨胀就是黑色被腐蚀。要注意的是,膨胀和腐蚀都是不可逆的,即两者不能完全的相互抵消。
因为没有想进一步做什么,只是想更好的理解膨胀腐蚀,本人偷懒直接借用了opencv中读取图像的函数,不过不是调用opencv内置的erode()/dilate()腐蚀膨胀函数。
#include "stdafx.h"
#include <opencv2\opencv.hpp>
using namespace cv;
enum op {
ERODE = 0, //
DILATE = 1
};
void erosion_dilation(int op, Mat binary, Mat element, Mat& dst)
{
binary.copyTo(dst);
for (int row = 1; row < binary.rows - 1; row++) //减去最边缘的元素
{
for (int col = 1; col < binary.cols - 1; col++)
{
if(!op) //腐蚀:与结构元素的白点全部相同,默认不变,否则变黑色
if (binary.at<char>(row - 1, col - 1) == element.at<char>(0, 0)
&& binary.at<char>(row - 1, col) == element.at<char>(0, 1)
&& binary.at<char>(row - 1, col + 1) == element.at<char>(0, 2)
&& binary.at<char>(row, col - 1) == element.at<char>(1, 0)
&& binary.at<char>(row, col + 1) == element.at<char>(1, 2)
&& binary.at<char>(row + 1, col - 1) == element.at<char>(2, 0)
&& binary.at<char>(row + 1, col) == element.at<char>(2, 1)
&& binary.at<char>(row + 1, col + 1) == element.at<char>(2, 2))
continue;
else
{
dst.at<char>(row, col) = 0;
}
else //膨胀:只要与结构元素的白点有一个相同,就将该点设为白色
if (binary.at<char>(row - 1, col - 1) == element.at<char>(0, 0)
|| binary.at<char>(row - 1, col) == element.at<char>(0, 1)
|| binary.at<char>(row - 1, col + 1) == element.at<char>(0, 2)
|| binary.at<char>(row, col - 1) == element.at<char>(1, 0)
|| binary.at<char>(row, col + 1) == element.at<char>(1, 2)
|| binary.at<char>(row + 1, col - 1) == element.at<char>(2, 0)
|| binary.at<char>(row + 1, col) == element.at<char>(2, 1)
|| binary.at<char>(row + 1, col + 1) == element.at<char>(2, 2))
{
dst.at<char>(row, col) = 255;
}
}
}
}
//腐蚀
void erosion(Mat binary, Mat element, Mat& dst)
{
erosion_dilation(ERODE, binary, element, dst);
}
//膨胀
void dilation(Mat binary, Mat element, Mat& dst)
{
erosion_dilation(DILATE, binary, element, dst);
}
int main()
{
Mat img = imread("D:\\456.JPG");
Mat gray, binary; //灰度图、二值图
cvtColor(img, gray, CV_BGR2GRAY); //原图转化为灰度图
threshold(gray, binary, 145, 255, THRESH_BINARY); //灰度图转化为二值图
namedWindow("二值图", WINDOW_AUTOSIZE);
imshow("二值图", binary);
Mat imgErode, imgDilate;
Mat element(3, 3, CV_8UC1, 255); //3*3白色矩阵结构元素,腐蚀膨胀时将浅色默认为骨架
//腐蚀
erosion(binary, element, imgErode);
namedWindow("腐蚀", WINDOW_AUTOSIZE);
imshow("腐蚀", imgErode);
//膨胀
dilation(binary, element, imgDilate);
namedWindow("膨胀", WINDOW_AUTOSIZE);
imshow("膨胀", imgDilate);
waitKey();
return 0;
}
原图
腐蚀效果图
膨胀效果图