Обрезка треугольника из захваченного кадра - OpenCV и C ++ - PullRequest
0 голосов
/ 13 октября 2018

У меня есть видеофайл, из которого я снимаю кадры.Я хочу обрезать треугольник из захваченного кадра и отобразить его, но моя программа показывает только исходный кадр.

Вот мой код:

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;
}

Вместо отображения исходного кадра я хочу этодля отображения обрезанного треугольника.

1 Ответ

0 голосов
/ 13 октября 2018

Поскольку вы используете CV_8UC3 в качестве типа result, я предполагаю (см. Редактирование в конце ответа, если это не так), что входное изображение frame также имеет 3 каналы.В этом случае я немного удивляюсь, что вы даже можете увидеть не обрезанное изображение, так как выполнение вашего кода просто вызывает на моей машине исключение при вызове bitwise_and:

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

From документация , мне кажется, что вы не можете смешивать разные типы ввода и маски.Быстрое и грязное решение состоит в том, чтобы разделить входное изображение на вектор из трех каналов, вызвать bitwise_and для каждого из них и затем объединить их обратно.Код ниже работает для меня:

#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; 
}

Редактировать: Из ваших комментариев кажется, что frame на самом деле в оттенках серого.В этом случае не обращайте внимания на весь код, приведенный выше, и просто измените cv::Mat result(frame.size(), CV_8UC3); на

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

в исходном коде.

...