【问题标题】:Opencv with Python: pointPolygonTest gives obviously wrong resultOpencv 与 Python:pointPolygonTest 给出明显错误的结果
【发布时间】:2015-08-09 13:54:43
【问题描述】:

我在下面有一个轮廓。由于我想提取此轮廓内的所有像素并将其他所有内容涂黑以消除噪音,因此我使用了 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 表示测试失败。

我还使用了一个 approxPolyDP 函数来尝试用更少的顶点来逼近轮廓。这一次返回了更多的积分。但是我不知道为什么!

感谢您的帮助。

【问题讨论】:

  • 怎么样:1) findContours,2) drawContours(... CV_FILLED ... 3) findNonZero(可选)?
  • 抱歉,但我不确定带有颜色填充的 drawContours 会如何产生影响,因为绘图函数肯定不会返回或修改任何现有对象......?
  • 你能上传一张png图片吗? jpeg 创建不需要的工件
  • 您好,我已将其更改为 png。
  • 我发布了一个答案,如果它符合您的需求,请告诉我

标签: python opencv image-processing computer-vision contour


【解决方案1】:

既然你有一个明确的轮廓,你可以简单地使用findContourCV_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;
}

【讨论】:

  • 您好,非常感谢您的回答。也许我应该说得更清楚。我有一个 numpy 数组 img,代表原始图像文件。另外,我有这个定义的轮廓。我想要一个名为filtered_img的numpy数组,这样轮廓外的每个像素的RGB值都为0,轮廓内的每个像素都具有与img对象中定义的相同的RGB值
  • @wudanao 检查更新的答案。获得遮罩后(使用drawContour 获得),使用copyTo 仅复制图像的遮罩部分。
  • 哇,这很漂亮,也很有前途。我忘记了 drawcontours 实际上修改了原始的 numpy 数组。我今晚会回去并尝试实施它。谢谢!
猜你喜欢
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-16
  • 2022-08-03
  • 1970-01-01
  • 2011-11-15
  • 2019-02-06
相关资源
最近更新 更多