c++ - ConvexPoly 不起作用后 OpenCV Canny

标签 c++ opencv affinetransform

我正在使用 c++ 中的 opencv 开发车道检测算法。 我进行了仿射变换,将三角形区域提取到蒙版中。

在这一步之后,我想执行 Canny 边缘检测器。但它不起作用。是因为位转换吗?或者我的问题是什么?

我将主要部分外包给了函数 warpTriangle。程序最后在此函数中中断。

错误消息:

OpenCV Error: Assertion failed ((_dst.getObj() != _src.getObj() || _src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3))) && "Inplace parameters are not supported") in Canny, file /tmp/opencv-20180113-80339-d8g5mw/opencv-3.4.0/modules/imgproc/src/canny.cpp, line 935 libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv-20180113-80339-d8g5mw/opencv-3.4.0/modules/imgproc/src/canny.cpp:935: error: (-215) (_dst.getObj() != _src.getObj() || _src.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3))) && "Inplace parameters are not supported" in function Canny

Screenshot

我的代码:

#include <opencv2/opencv.hpp>
#include <stdlib.h>
#include <chrono>
#include <thread>

using namespace cv;
using namespace std;

// Warps and alpha blends triangular regions from img1 and img2 to img
void warpTriangle(Mat &img1, Mat &img2, vector<Point2f> tri)
{
    // Find bounding rectangle for each triangle
    Rect r1 = boundingRect(tri);
    Rect r2 = boundingRect(tri);

    // Offset points by left top corner of the respective rectangles
    vector<Point2f> tri1Cropped, tri2Cropped;
    vector<Point> tri2CroppedInt;
    for(int i = 0; i < 3; i++)
    {
        tri1Cropped.push_back( Point2f( tri[i].x - r1.x, tri[i].y -  r1.y) );
        tri2Cropped.push_back( Point2f( tri[i].x - r2.x, tri[i].y - r2.y) );

        // fillConvexPoly needs a vector of Point and not Point2f
        tri2CroppedInt.push_back( Point((int)(tri[i].x - r2.x), (int)(tri[i].y - r2.y)) );

    }

    // Apply warpImage to small rectangular patches
    Mat img1Cropped;
    img1(r1).copyTo(img1Cropped);

    // Given a pair of triangles, find the affine transform.
    Mat warpMat = getAffineTransform( tri1Cropped, tri2Cropped );

    // Apply the Affine Transform just found to the src image
    Mat img2Cropped = Mat::zeros(r2.height, r2.width, img1Cropped.type());
    warpAffine( img1Cropped, img2Cropped, warpMat, img2Cropped.size(), INTER_LINEAR, BORDER_REFLECT_101);

    // Get mask by filling triangle
    Mat mask = Mat::zeros(r2.height, r2.width, CV_32FC3);
    fillConvexPoly(mask, tri2CroppedInt, Scalar(1.0, 1.0, 1.0), 16, 0);
    imshow("mask", mask);
    // Copy triangular region of the rectangular patch to the output image

    multiply(img2Cropped,mask, img2Cropped);

    img2Cropped.convertTo(img2Cropped, CV_8U);
    imshow("img2Cropped",img2Cropped);
    Canny(img2Cropped, img2Cropped, 50, 150);   <--- Breaks here!

}

int main( int argc, char** argv)
{

  //  VideoCapture cap(0);
    // Challenge video
    VideoCapture cap("/Users/markus/Desktop/challenge.mp4");
    Mat imgIn;
    while (true)
    {
        Mat start;

        Mat frame = Mat(320,480, CV_8U, 0.0);
        cap >> start;

        resize(start, frame, frame.size());

        cout << "h: " << frame.rows << " w: " << frame.cols << endl;

        Mat imgIn = frame;

        // Read input image and convert to float
        imgIn.convertTo(imgIn, CV_32FC3, 1/255.0);

        // Output image is set to white
        Mat imgOut = Mat::ones(imgIn.size(), imgIn.type());
        imgOut = Scalar(0.0,0.0,0.0);

        int height, width;
        height = frame.rows;
        width = frame.cols;
        // Input triangle
        vector <Point2f> triIn;
        triIn.push_back(Point2f(0,height-1));
        triIn.push_back(Point2f(width-1,height-1));
        triIn.push_back(Point2f(width/2-1,height/2-1));

        // Warp all pixels inside input triangle to output triangle
         warpTriangle(imgIn, imgOut, triIn);

        // Draw triangle on the input and output image.

        // Convert back to uint because OpenCV antialiasing
        // does not work on image of type CV_32FC3

        imgIn.convertTo(imgIn, CV_8UC3, 255.0);
        imgOut.convertTo(imgOut, CV_8UC3, 255.0);

        // Draw triangle using this color
        Scalar color = Scalar(255, 150, 0);

        // cv::polylines needs vector of type Point and not Point2f
        vector <Point> triInInt, triOutInt;
        for(int i=0; i < 3; i++)
        {
            triInInt.push_back(Point(triIn[i].x,triIn[i].y));
        }

        // Draw triangles in input and output images
        polylines(imgIn, triInInt, true, color, 2, 16);
        polylines(imgOut, triOutInt, true, color, 2, 16);

        imshow("frame", imgIn);


        if (waitKey(30) >= 0) {
            break;
        }
    }
    return 0;
}

最佳答案

错误已经告诉你出了什么问题

_dst.getObj() != _src.getObj()

这意味着源对象和目标对象不应该相同...

在您的代码中:

Canny(img2Cropped, img2Cropped, 50, 150); 

如您所见,您具有与源和目标相同的变量 (img2Cropped)。要修复它,请将其更改为:

Mat resultCanny;
Canny(img2Cropped, resultCanny, 50, 150); 

关于c++ - ConvexPoly 不起作用后 OpenCV Canny,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48296445/

相关文章:

C++ - unsigned long long 到有符号 long long 的隐式转换?

c++ - 模板特化和引用

c++ - 执行时间比较

ios - 如何可靠地围绕一个点旋转图像?

c++ - 使用同一类的函数在类内创建线程

python - 具有DNN的OpenCv

opencv - 使用对象 CAD 从单个图像中获得 3D 对象姿势

python - 从灰度图片创建彩色图片

java - 如何在 Java 中旋转 imageIcon

javascript - 如何将矩阵的旋转设置为围绕给定点的绝对弧度值?