note
// 膨胀原理:操作过程中,若膨胀因子某点是1,且原图该点为1,则锚点位置为1
code
// 膨胀
// 膨胀原理:操作过程中,若膨胀因子某点是1,且原图该点为1,则锚点位置为1
typedef enum {
MY_EXPAND_NONE,
MY_EXPAND_HORIZON, // 水平膨胀
MY_EXPAND_VERTIC, // 竖直膨胀
MY_EXPAND_RECTANGLE, // 矩形膨胀
MY_EXPAND_CROSS, // 十字架膨胀
}my_expand_t;
void MyExpandHorizon(Mat& src, Mat& res, uchar threshold = 255) {
src.copyTo(res);
Mat kernel = (Mat_<uchar>(1,3) << 0,255,0);
int anchor = kernel.cols / 2;
for (int r = 0; r+kernel.rows <= res.rows; r=r+kernel.rows) {
for (int c = 0; c+kernel.cols <= res.cols; c = c+kernel.cols) {
if (res.at<uchar>(r,c) >= threshold || res.at<uchar>(r,c+kernel.cols-1) >= threshold) {
res.at<uchar>(r,c+anchor) = 255;
}
}
}
}
void MyExpandVertic(Mat& src, Mat& res, uchar threshold = 255) {
src.copyTo(res);
Mat kernel = (Mat_<uchar>(3,1) << 0,255,0);
int anchor = kernel.rows / 2;
for (int c = 0; c+kernel.cols <= res.cols; c=c+kernel.cols) {
for (int r = 0; r+kernel.rows <= res.rows; r=r+kernel.rows) {
if ((res.at<uchar>(r,c) >= threshold) || (res.at<uchar>(r+kernel.rows-1) >= threshold)) {
res.at<uchar>(r+anchor,c) = 255;
}
}
}
}
void MyExpandRect(Mat& src, Mat& res, uchar threshold = 255) {
src.copyTo(res);
Mat kernel = (Mat_<uchar>(3,3) << 255,255,255,255,255,255,255,255,255);
int anchor = kernel.rows / 2;
bool flag = false;
for (int r = 0; r+kernel.rows <= res.rows; r=r+kernel.rows) {
for (int c = 0; c+kernel.cols <= res.cols; c=c+kernel.cols) {
flag = false;
for (int i = 0; i < kernel.rows; ++i) {
for (int j = 0; j < kernel.cols; ++j) {
if (res.at<uchar>(r+i,c+j) >= threshold) {
flag = true;
break;
}
}
if (flag) {
res.at<uchar>(r+anchor,c+anchor) = 255;
break;
}
}
}
}
}
void MyExpandCross(Mat& src, Mat& res, uchar threshold = 255) {
src.copyTo(res);
Mat kernel = (Mat_<uchar>(3,3) << 0,255,0,255,255,255,0,255,0);
int anchor = kernel.rows / 2;
bool flag = false;
for (int r = 0; r+kernel.rows <= res.rows; r=r+kernel.rows) {
for (int c = 0; c+kernel.cols <= res.cols; c=c+kernel.cols) {
flag = false;
for (int i = 0; i < kernel.rows; ++i) {
for (int j = 0; j < kernel.cols; ++j) {
if (kernel.at<uchar>(i,j) == 255 && res.at<uchar>(r+i,c+j) >= threshold) {
flag = true;
break;
}
}
if (flag) {
res.at<uchar>(r+anchor,c+anchor) = 255;
break;
}
}
}
}
}
void MyExpand(my_expand_t type, Mat& src, Mat& res) {
switch (type) {
case MY_EXPAND_HORIZON:
MyExpandHorizon(src, res, 255);
break;
case MY_EXPAND_VERTIC:
MyExpandVertic(src, res, 255);
break;
case MY_EXPAND_RECTANGLE:
MyExpandRect(src, res, 255);
break;
case MY_EXPAND_CROSS:
MyExpandCross(src, res, 255);
break;
default:
break;
}
}
void MyExpandTest(void) {
Mat src = imread("../source/LinuxLogo.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
return;
}
Mat res;
namedWindow("src", WINDOW_NORMAL);
namedWindow("res", WINDOW_NORMAL);
threshold(src, src, 0, 255, THRESH_BINARY|THRESH_OTSU);
MyExpand(MY_EXPAND_RECTANGLE, src, res);
imshow("src", src);
imshow("res", res);
MyWait();
destroyAllWindows();
}
test