我试图在opencv中使用matchshapes()函数比较两个轮廓
这些是我想要比较的两个图像
问题是matchshapes()显示这两个图像几乎匹配,即返回一个非常小的值。我不知道我们是否可以使用matchshapes()来比较不同的轮廓形状
你能否提出一些方法来比较手的不同轮廓形状?
这是我的代码..
#include <opencv2\opencv.hpp>
#include <string>
using namespace cv;
using std::cout;
Mat1b converttogray(Mat3b testcases);
int findmaxcontour(vector<vector<Point>> contours);
RNG rng(12345);
vector<vector<Point>> getcontours(Mat1b image_gray, int i);
/*--------------- SKIN SEGMENTATION ---------------*/
int main()
{
Mat1b image_gray;
int max_contour;
vector<vector<Point> > contours;
vector<vector<Point> > contours2;
Mat3b first;
Mat3b frame;
Mat1b frame_gray;
String one = "E:/photo/" + std::to_string((0 + 5));
String a = "a.png";
String b = "b.png";
String c = "c.png";
cout << one + a << "\n";
cout << one + b << "\n";
cout << one + c << "\n";
first = imread(one + c, CV_LOAD_IMAGE_COLOR);
image_gray = converttogray(first);
contours = getcontours(image_gray, 1);
max_contour = findmaxcontour(contours);
frame = imread("E:/photo/1.png", CV_LOAD_IMAGE_COLOR);
frame_gray = converttogray(frame);
contours2 = getcontours(frame_gray, 2);
int x = findmaxcontour(contours2);
cout << "\n" << matchShapes(contours[max_contour], contours2[x], CV_CONTOURS_MATCH_I1, 0.0);
waitKey(0);
}
Mat1b converttogray(Mat3b testcases)
{
Mat1b image_gray;
cvtColor(testcases, testcases, CV_BGR2HSV);
GaussianBlur(testcases, testcases, Size(7, 7), 1, 1);
medianBlur(testcases, testcases, 15);
for (int r = 0; r<testcases.rows; ++r)
{
for (int c = 0; c<testcases.cols; ++c)
// 0<H<0.25 - 0.15<S<0.9 - 0.2<V<0.95
if ((testcases(r, c)[0]>5) && (testcases(r, c)[0] < 17) && (testcases(r, c)[1]>38) && (testcases(r, c)[1]<250) && (testcases(r, c)[2]>51) && (testcases(r, c)[2]<242)); // do nothing
else for (int i = 0; i<3; ++i) testcases(r, c)[i] = 0;
}
cvtColor(testcases, testcases, CV_HSV2BGR);
cvtColor(testcases, image_gray, CV_BGR2GRAY);
threshold(image_gray, image_gray, 30, 255, CV_THRESH_BINARY);
morphologyEx(image_gray, image_gray, CV_MOP_ERODE, Mat1b(3, 3, 1), Point(-1, -1), 3);
morphologyEx(image_gray, image_gray, CV_MOP_OPEN, Mat1b(7, 7, 1), Point(-1, -1), 1);
morphologyEx(image_gray, image_gray, CV_MOP_CLOSE, Mat1b(9, 9, 1), Point(-1, -1), 1);
medianBlur(image_gray, image_gray, 15);
return image_gray;
}
int findmaxcontour(vector<vector<Point>> contours)
{
int largest_area = 0;
int largest_contour_index = 0;
for (int i = 0; i< contours.size(); i++) // iterate through each contour.
{
double a = contourArea(contours[i], false); // Find the area of contour
cout << a << "\n";
if (a>largest_area)
{
largest_area = a;
largest_contour_index = i; //Store the index of largest contour
}
}
return largest_contour_index;
}
vector<vector<Point>> getcontours(Mat1b image_gray, int i)
{
Mat canny_output;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Canny(image_gray, canny_output, 50, 150, 3);
int x=0;
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
x = findmaxcontour(contours);
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, x, color, 2, 8, hierarchy, 0, Point());
}
/// Show in a window
namedWindow(std::to_string(i), CV_WINDOW_AUTOSIZE);
imshow(std::to_string(i), drawing);
return contours;
}