我的轮廓如下。因为我想提取这个轮廓中的所有像素并将其他所有像素都去除以去除噪声,所以我使用了cv2.pointPolygonTest来实现此目的。
以下是我用来尝试创建蒙版的代码。
inside_or_not = np.zeros(img.shape[:2],dtype = np.int32)
for i in range(0,img.shape[0]):
for j in range(0,img.shape[1]):
inside_or_not[i,j] = cv2.pointPolygonTest(body_line,(i,j),False)
只发现了2分。最重要的是,我期望轮廓上的点数,因此从cv2.pointPolygonTest返回0应该与定义轮廓的像素数匹配。但是当我运行sum(sum(inside_or_not == 0))时,它与轮廓上的像素数不匹配。 我还用鼠标点击了一个明显位于轮廓内部的点并将该点放入测试中;但返回-1表示测试失败。
我还使用了一个近似函数来尝试用较少的顶点逼近轮廓。这一次返回了更多的积分。但是我不明白为什么!
感谢任何帮助,谢谢。
答案 0 :(得分:1)
由于您有一个定义明确的轮廓,您只需使用findContour
和CV_RETR_EXTERNAL
来检测外部轮廓,然后使用drawContour(..., CV_FILLED)
绘制其中的区域。获得蒙版后,您可以使用copyTo
根据蒙版仅复制原始图像的各个部分。
这里有一个例子,它是C ++,但是移植到python很简单。
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// Load image
Mat3b img = imread("path_to_image_shape");
// Just to have a background image the same size of your image.
Mat3b bkg = imread("path_to_image_background");
resize(bkg, bkg, img.size());
// Convert to gray
Mat1b gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
// Get external contour
vector<vector<Point>> contours;
findContours(gray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// contours has size 1 here, you need to check this in a real application
// Create a mask with the inner part of the contour
Mat1b mask(img.size(), uchar(0));
drawContours(mask, contours, 0, Scalar(255), CV_FILLED);
// Create a black RGB image
Mat3b res(img.size(), Vec3b(0,0,0));
// Copy the image according to the mask
bkg.copyTo(res, mask);
imshow("result", res);
waitKey();
return 0;
}