【问题标题】:Why are the sizes of the Mat's different?为什么垫子的尺寸不一样?
【发布时间】:2018-01-02 01:59:48
【问题描述】:

我尝试从图像中裁剪出非矩形垫。遵循了很多教程,现在我为我的目的实现了这个方法:

void crop(Mat src) {
Scalar mu, sigma;
meanStdDev(src, mu, sigma);

Canny(src, dst, mu.val[0] - sigma.val[0], mu.val[0] + sigma.val[0], 3, false);
cvtColor(dst, cdst, CV_GRAY2BGR);

HoughLinesP(dst, lines, 1, CV_PI / 2, 100, 50, 100);

Vec4i current, previous;
Point pt1, pt2, ppt1, ppt2;

for (size_t i = 1; i < lines.size(); i++) {
    current = lines[i];
    pt1 = Point(current[0], current[1]);
    pt2 = Point(current[2], current[3]);

    previous = lines[i - 1];
    ppt1 = Point(previous[0], previous[1]);
    ppt2 = Point(previous[2], previous[3]);

    vector<Point> pt;
    pt.push_back(Point(previous[2], previous[3]));                              
    pt.push_back(Point(previous[0], previous[1]));
    pt.push_back(Point(current[0], current[1]));
    pt.push_back(Point(current[2], current[3]));

    Rect roi = boundingRect(pt);    
    contourRegion = src(roi);

    Mat mask = Mat::zeros(contourRegion.size(), CV_8UC3);
    vector<Point> ROI_Poly;
    approxPolyDP(pt, ROI_Poly, 1.0, true);
    fillConvexPoly(mask, &ROI_Poly[0], ROI_Poly.size(), 255, 8, 0);

    Mat result = Mat(contourRegion.size(), CV_8UC3);
    try {
        src.copyTo(result, mask);
        imshow("result", result);
        imshow("contReg", contourRegion);
    } catch (Exception e) {}
}

编译后出现异常:OpenCV Error: Assertion failed (size() == mask.size()) in cv::Mat::copyTo 但为什么呢?实际上我将Mat 都设置为contourRegion.size 所以应该是同一个?

作为参考,这里是原图:

【问题讨论】:

  • 您确定您的蒙版与您的输入图像 (src) 大小相同吗?

标签: c++ opencv crop opencv3.0 roi


【解决方案1】:

最初的答案是错误的。这是修复

copyTo 中,掩码便于指示需要复制哪些矩阵元素,因此必须与源src 具有相同的大小。请参阅文档here。此外,您的面罩必须激活所有三个通道。因此,以下代码应该可以工作:

int main(int argc, char **argv)
{
vector<Point> pt;
pt.push_back(cv::Point(10, 10));
pt.push_back(cv::Point(100, 20));
pt.push_back(cv::Point(200, 300));
pt.push_back(cv::Point(10, 120));
cv::Mat src = cv::imread(argv[1]);

Rect roi = boundingRect(pt);
cv::Mat contourRegion = src(roi);

Mat mask = Mat::zeros(contourRegion.size(), CV_8UC3);
vector<Point> ROI_Poly;
approxPolyDP(pt, ROI_Poly, 1.0, true);
fillConvexPoly(mask, &ROI_Poly[0], ROI_Poly.size(), 255, 8, 0);
cv::Mat f_mask = cv::Mat(src.size(), CV_8UC3);
f_mask.setTo(0);

// duplicate the mask on three channels
cv::Mat bgr_mask[3];
split(mask,bgr_mask);
cv::Mat in[] = {bgr_mask[0],bgr_mask[0],bgr_mask[0]};
cv::merge(in, 3, mask);

// copy the mask to a "full mask" of the same size as the image
mask.copyTo(f_mask(roi));

Mat result = Mat(src.size(), CV_8UC3);
try {
    src.copyTo(result, f_mask);
    imshow("result", result);
    imshow("src", src);
    cv::imshow("contReg", contourRegion);
    cv::waitKey(0);

} catch (Exception e) {}

return 0;
}

在众所周知的lena picture 上,它给出:

要获得与contourRegion 相同大小的结果,请使用:

imshow("result", result(roi));

你有:

【讨论】:

  • 仍然出现异常,因为我希望裁剪后的图像大小为contourRegion
  • 我已经编辑了这个帖子:让我们使用result(roi)而不是result
  • 不幸的是,没有。我只是得到一张黑色图像。
  • 你至少能用lena.png 图像重现我的例子吗?否则,将链接添加到您的一张图片和您想要的确切点,我会在我这边尝试。
  • 我已经尝试过您的示例,但它也不起作用.. :( 好的,我编辑了我的问题并为您提供了所有需要的信息。感谢您的努力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-31
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
相关资源
最近更新 更多