我正在编写一个简单的 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 都是我想要的最终结果。你希望我使用这个轮廓中的任何一个,选择任何一个都可以。但是如果我画很多形状怎么办,因为每个形状都生一个兄弟,那么整理起来就很复杂
这是我期望的最终结果,裁剪后的图像