0

我正在编写一个简单的 opencv 程序来提取图像并从我自己绘制的策略中获取图像矩阵。下面的代码给出了一个绘制带有几个点的多边形的示例,当我用红色绘制完多边形时,我想使用 findContours 从图片中提取唯一的多边形并从该轮廓中获取矩阵。

#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
Mat grey_img;
Mat img_resized;
bool start = 0;
cv::Point lastPoint =  Point(-1,-1);
vector<Point> parkspoint;
void mouseMode2(int event, int x, int y, void* param);
void mouseHandler(int event, int x, int y, int flags, void* param);

void mouseHandler(int event, int x, int y, int flags, void* param){
    mouseMode2(event,x,y,param);
}

void mouseMode2(int event, int x, int y, void* param){
    //Boolean select_flag = CV_EVENT_FLAG_SHIFTKEY; 
    if (event == CV_EVENT_LBUTTONDOWN && start)
    {
        cout<<"select one point  "<<x<<"   "<< y<<endl;
        cv::Point point = cv::Point(x, y);

        cout<<"last point   x:"<<lastPoint.x <<"    y:"<<lastPoint.y<<endl; 
        //  add point
        if(lastPoint.x!=-1 && lastPoint.y!=-1){
           cv::line(img_resized, lastPoint, point, CV_RGB(255, 0, 0), 1, 1, 0);
           cv::imshow("parking", img_resized);
        }
        cout<<"add point to array"<<endl;
        lastPoint =  Point(x,y);        
        parkspoint.push_back(point);
    }

    if (event == CV_EVENT_MOUSEMOVE && start){
        cv::Point point = cv::Point(x, y);
        if(lastPoint.x!=-1 && lastPoint.y!=-1)
        {
            cv::Mat img1 = img_resized.clone();
            cv::line(img1, lastPoint, point, CV_RGB(255, 0, 0), 1, 1, 0);
            cv::imshow("parking", img1);
        }
    }

    if (event == CV_EVENT_RBUTTONUP )
    {
        cout<<"end selecting"<<endl;
        start = 0;
        if(lastPoint.x!=-1 && lastPoint.y!=-1){
            cv::line(img_resized, lastPoint, parkspoint[0], CV_RGB(255, 0, 0), 1, 1, 0);
            cv::imshow("parking", img_resized);
        }
        for(int i=0;i<parkspoint.size();i++){
            cout<<"show points "<<i<<"     "<< parkspoint[i].x<<":"<< parkspoint[i].y <<endl;
        }

        std::vector<std::vector<cv::Point> > contours;
        cv::imshow("parking", img_resized);

        cv::findContours(img_resized,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
        cout<<"find  how many coutours  : "<< contours.size()<< endl;
        for(int i = 0;i <contours.size();i++){
           cv::drawContours(grey_img,contours,i,cv::Scalar(255,0,0),1);
        }
        cv::imshow("parking2", grey_img);
    }

    if (event == CV_EVENT_RBUTTONDOWN )
    {
        cout<<"start selecting"<<endl;
        start = 1;
    }
}

int main(int argc, char* argv[])
{
    Mat img_raw = imread("D:/car parking/bb.jpg", 1); // load as color image

    resize(img_raw, img_resized, Size(64,128) );
    grey_img = img_resized.clone();

    cout << "raw img dimensions: " << img_raw.cols << " width x " << img_raw.rows << "height" << endl;
    cout << "img dimensions: " << img_resized.cols << " width x " << img_resized.rows << "height" << endl; 

    cv::cvtColor(img_resized,img_resized,CV_BGR2GRAY);
   namedWindow("parking",CV_WINDOW_NORMAL);
   imshow("parking",img_resized);
   namedWindow("parking2",CV_WINDOW_NORMAL);
   imshow("parking2",grey_img);
   cv::setMouseCallback("parking",mouseHandler,0);
   waitKey(0);
   return 0;
}

但是,我遇到的问题是在此处输入图像描述,左边的图像是我自己绘制的多边形,当使用 findContour 时,它给了我三个多边形。

首先,最大的轮廓是整个图片的矩形,我不想要它,我可以比较轮廓的大小来摆脱它,但是如果有任何其他好的/聪明的方法来摆脱大矩形在前面。

其次,有两个轮廓非常相似,更像是我绘制的形状的外边界和内边界,任何轮廓的 Mat 都是我想要的最终结果。你希望我使用这个轮廓中的任何一个,选择任何一个都可以。但是如果我画很多形状怎么办,因为每个形状都生一个兄弟,那么整理起来就很复杂

这是我期望的最终结果,裁剪后的图像 在此处输入图像描述

4

0 回答 0