形态学操作之膨胀

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值