OpenCV——形态学之凸壳

参考:https://blog.csdn.net/webzhuce/article/details/100402522

在这里插入图片描述

#include<iostream>
#include<opencv2\opencv.hpp>


using namespace std;
using namespace cv;

void	CostomErode(const Mat &src, Mat &dst, int se[3][3])
{
	bool match = true;
	for (int i = 1; i < src.rows - 1; i++)
	{
		uchar* data = dst.ptr<uchar>(i);
		for (int j = 1; j < src.cols - 1; j++)
		{
			match = true;
			for (int m = 0; m < 3; m++)
			for (int n = 0; n < 3; n++)
			{
				if (se[m][n] == -1)
					continue;
				else if (se[m][n] == 1)
				{
					if (src.at<uchar>(i - 1 + m, j - 1 + n) != 255)
					{
						match = false;
						break;
					}
				}
				else if (se[m][n] == 0)
				{
					if (src.at<uchar>(i - 1 + m, j - 1 + n) != 0)
					{
						match = false;
						break;
					}
				}

			}//for n
			if (match)
				data[j] = 255;
		}
	}
}


void ConvexShell(Mat &src, Mat &dst, bool constrain)
{
	int se1[3][3] = { { 1, 1, 1 },
	{ -1, 0, -1 },
	{ -1, -1, -1 } };

	int se2[3][3] = { { -1, -1, -1 },
	{ -1, 0, -1 },
	{ 1, 1, 1 } };

	int se3[3][3] = { { -1, -1, 1 },
	{ -1, 0, 1 },
	{ -1, -1, 1 } };

	int se4[3][3] = { { 1, -1, -1 },
	{ 1, 0, -1 },
	{ 1, -1, -1 } };

	Mat backsrc1;
	src.copyTo(backsrc1);
	while (true)//结构一
	{
		CostomErode(backsrc1, dst, se1);
		bitwise_or(dst, backsrc1, dst);
		if (cv::countNonZero(dst - backsrc1) == 0)
		{
			break;
		}
		dst.copyTo(backsrc1);
	}

	while (true)//结构二
	{
		CostomErode(backsrc1, dst, se2);
		bitwise_or(dst, backsrc1, dst);
		if (cv::countNonZero(dst - backsrc1) == 0)
		{
			break;
		}
		dst.copyTo(backsrc1);
	}

	while (true)//结构三
	{
		CostomErode(backsrc1, dst, se3);
		bitwise_or(dst, backsrc1, dst);
		if (cv::countNonZero(dst - backsrc1) == 0)
		{
			break;
		}
		dst.copyTo(backsrc1);
	}

	while (true)//结构四
	{
		CostomErode(backsrc1, dst, se4);
		bitwise_or(dst, backsrc1, dst);
		if (cv::countNonZero(dst - backsrc1) == 0)
		{
			break;
		}
		dst.copyTo(backsrc1);
	}

	if (constrain)
	{
		int top = 0;
		int bottom = src.rows;
		int left = 0;
		int right = src.cols;

		for (int i = 0; i < src.rows; i++)
		for (int j = 0; j < src.cols; j++)
		{
			if (src.at<uchar>(i, j) == 0)
				continue;
			if (i>top)
				top = i;
			if (i < bottom)
				bottom = i;
			if (j>left)
				left = j;
			if (j < right)
				right = j;
		}
		for (int i = 0; i < src.rows; i++)
		{
			for (int j = 0; j < src.cols; j++)
			{
				if (i<top || i>bottom || j<left || j>right)
					dst.at<uchar>(i, j) = 0;
			}
		}


	}


}


void main()
{
	Mat src = imread("ConvexShell222..png", 0);


	Mat image = src.clone();
	image = Scalar::all(255) - image;
	Mat dst = image.clone();

	ConvexShell(image, dst, false);
	imshow("src", src);
	imshow("image", image);
	imshow("dst", dst);
	cv::waitKey(0);
}

请看我漂亮的坚持

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vector_LW

我们终将成龙 加油

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值