参考: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);
}
请看我漂亮的坚持