简体   繁体   English

从捕获的帧裁剪三角形-OpenCV和C ++

[英]Cropping an triangle from captured frame - OpenCV and C++

I have a video file from which I'm capturing a frames. 我有一个视频文件,正在从中捕获帧。 I want to crop a triangle from captured frame and display it, but my program shows just a source frame. 我想从捕获的帧中裁剪一个三角形并显示它,但是我的程序仅显示一个源帧。

Here is my code: 这是我的代码:

cv::Mat Detector::cropRegionOfInterest(cv::Mat& frame)
{
    cv::Point corners[1][3];
    corners[0][0] = cv::Point(0, frameHeight);
    corners[0][1] = cv::Point(frameWidth, frameHeight);
    corners[0][2] = cv::Point(frameWidth / 2, frameHeight / 2);

    const cv::Point* cornerList[1] = { corners[0] };

    int numPoints = 3;
    int numPolygons = 1;

    cv::Mat mask(frame.size(), CV_8UC1, cv::Scalar(0, 0, 0));
    cv::fillPoly(mask, cornerList, &numPoints, numPolygons, cv::Scalar(255, 255, 255), 8);

    cv::Mat result(frame.size(), CV_8UC3);
    cv::bitwise_and(frame, mask, result);

    return result;
}

Instead of displaying source frame I want it to display cropped triangle. 我希望它不显示源框架,而是显示裁剪的三角形。

Since you're using CV_8UC3 as the type of result , I'm assuming (see the Edit at the end of the answer if that's not the case) that the input image frame also has 3 channels. 由于您使用CV_8UC3作为result类型, result我假设(如果不是result ,请参见答案末尾的Edit)输入图像frame也具有3通道。 In that case, I'm a bit surprised that you can even see the non-cropped image, as running your code simply throws an exception on my machine at the call to bitwise_and : 在那种情况下,您甚至可以看到未裁剪的图像,让我有些惊讶,因为运行代码只是在调用bitwise_and在我的计算机上引发异常:

OpenCV(3.4.1) Error: Sizes of input arguments do not match

From the documentation , it seems to me that you can't mix different input and mask types. 根据文档 ,在我看来您不能混合使用不同的输入和掩码类型。 A quick and dirty solution is to split the input image into a vector of three channels, call bitwise_and for each of them, and then merge them back. 一种快速而肮脏的解决方案是将输入图像分成三个通道的向量, bitwise_and对每个通道调用bitwise_and ,然后将它们合并回去。 The code below works for me: 以下代码对我有用:

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;


cv::Mat cropRegionOfInterest(cv::Mat& frame)
{

    const int frameWidth=frame.cols-1;
    const int frameHeight=frame.rows-1;
    cv::Point corners[1][3];
    corners[0][0] = cv::Point(0, frameHeight);
    corners[0][1] = cv::Point(frameWidth, frameHeight);
    corners[0][2] = cv::Point(frameWidth / 2, frameHeight / 2);

    const cv::Point* cornerList[1] = { corners[0] }; 

    int numPoints = 3; 
    int numPolygons = 1; 

    cv::Mat mask(frame.rows,frame.cols, CV_8UC1, cv::Scalar(0, 0, 0));
    cv::fillPoly(mask, cornerList, &numPoints, numPolygons, cv::Scalar(255, 255, 255), 8);

    std::vector<cv::Mat> src_channels;
    std::vector<cv::Mat> result_channels;
    cv::split(frame,src_channels);

    for(int idx=0;idx<3;++idx)
    {  
      result_channels.emplace_back(frame.rows,frame.cols,CV_8UC1);
      cv::bitwise_and(src_channels[idx], mask,result_channels[idx]);

    }  
    cv::Mat result;
    cv::merge(result_channels,result);
    return result;
}


int main(int argc, char** argv )
{
    if ( argc != 2 )
    {  
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }  

    Mat image;
    image = imread( argv[1], 1 ); 

    if ( !image.data )
    {  
        printf("No image data \n");
        return -1;
    }  

    cv::Mat cropped=cropRegionOfInterest(image);

    namedWindow("cropped Image", WINDOW_AUTOSIZE ); 
    imshow("cropped Image", cropped);

    waitKey(0);

    return 0; 
}

Edit: From your comments it seems that frame is actually grayscale. 编辑:从您的评论看来, frame实际上是灰度的。 In that case, nevermind all the code above, and just change cv::Mat result(frame.size(), CV_8UC3); 在那种情况下, cv::Mat result(frame.size(), CV_8UC3);上面的所有代码,而只需更改cv::Mat result(frame.size(), CV_8UC3); to

cv::Mat result(frame.rows,frame.cols,CV_8UC1);

in your original code. 在您的原始代码中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM