画像を抽出し、自分で描いた策略から画像のマトリックスを取得する簡単な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 を適用すると 3 つのポリゴンが作成されるという問題に遭遇しました。
まず、最大の輪郭は画像全体の長方形です。これは望ましくありません。輪郭のサイズを比較してそれを取り除くことができますが、大きな輪郭を取り除くための他の良い/スマートな方法があれば前の長方形。
第二に、私が描く形状の外側と内側の境界線のように、非常に似ている2つの輪郭があり、どの輪郭のマットも最終結果に必要なものです。この輪郭のいずれかを使用することを期待していますが、どれを選んでもかまいません。でも、たくさんの形を描いたら、形ごとに兄弟が生まれるので、それらを整理するのは複雑です
これは私が期待する最終結果であり、トリミングされた画像です