2017-04-10 9 views
1

輪郭の中心から、最も近い黒のピクセルまたは非輪郭のピクセルの点までの点を探したいと思います。私は中心からその点まで直線を作りたいと思います。ここにある私の現在のコードです:OpenCVとC++で輪郭の中心から最も近い黒のピクセルを見つける

#include<iostream> 
#include<opencv2\highgui\highgui.hpp> 
#include<opencv2\imgproc\imgproc.hpp> 
#include<opencv2\core\core.hpp> 
#include<opencv2/opencv.hpp> 
#include<opencv2/core/core.hpp> 
#include<opencv2/imgproc/imgproc.hpp> 
#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/objdetect/objdetect.hpp> 
#include<Windows.h> 
#include <sstream> 
using namespace cv; 
using namespace std; 

void on_trackbar(int, void*); 
void createTrackbars(); 
void morphit(Mat &img); 
void toggle(int); 

const int MAX_NUM_OBJECTS = 500; 

const int FRAME_WIDTH = 900; 
const int FRAME_HEIGHT = 600; 

const int MIN_OBJECT_AREA = 20 * 20; 
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5; 

Point middle; 

int l_MIN = 30; 
int l_MAX = 165; 
int a_MIN = 139; 
int a_MAX = 165; 
int b_MIN = 136; 
int b_MAX = 172; 

int kerode = 2; 
int kdilate = 5; 

bool domorph = true; 
bool showchangedframe = true; 

int main(int argc, char** argv) 
{ 
    createTrackbars(); 
    on_trackbar(0, 0); 

    int x, y; 
    Mat frame, labframe, rangeframe; 
    Mat newframe, newrf; 
    int key; 
    //VideoCapture cap(0); 

    while ((key = waitKey(30)) != 27) 
    { 
     toggle(key); 
     frame = imread(argv[1], 1); 
     newframe = imread(argv[1], 1); 
     //cap >> frame; 
     //cap >> newframe; 
     //flip(frame, frame, 180); 
     //flip(newframe, newframe, 180); 
     newframe = Scalar(0, 0, 0); 
     cvtColor(frame, labframe, COLOR_BGR2Lab); 
     inRange(labframe, Scalar(l_MIN, a_MIN, b_MIN), Scalar(l_MAX, a_MAX, b_MAX), rangeframe); 
     newrf = rangeframe.clone(); 

     int largest_area = 0; 
     int largest_contour_index = 0; 
     vector<vector<Point> > contours; 

     findContours(newrf, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); 

     vector<Moments> mu(contours.size()); //get moments 
     for (int i = 0; i < contours.size(); i++) 
     { 
      mu[i] = moments(contours[i], false); 
     } 

     vector<Point2f> mc(contours.size()); //get centers 
     for (int i = 0; i < contours.size(); i++) 
     { 
      mc[i] = Point2f(mu[i].m10/mu[i].m00, mu[i].m01/mu[i].m00); 
     } 

     for (int i = 0; i < contours.size(); i++) //iterate through each contour. 
     { 
      double a = contourArea(contours[i], false); //Find the area of contour 

      if (a>largest_area) 
      { 
       largest_area = a; 
       largest_contour_index = i;    //Store the index of largest contour 
      } 
     } 

     drawContours(newframe, contours, largest_contour_index, CV_RGB(255, 0, 0), CV_FILLED); 
     circle(newframe, mc[largest_contour_index], 5, CV_RGB(255, 255, 0), -1, 8, 0); 

     imshow("Detected", newframe); 

     if (showchangedframe) 
      imshow("Camera", frame); 

     else 
      imshow("Camera", rangeframe); 
    } 
} 

void on_trackbar(int, void*) 
{ 
    if (kerode == 0) 
     kerode = 1; 
    if (kdilate == 0) 
     kdilate = 1; 
} 

void createTrackbars() 
{ 
    String trackbarWindowName = "TrackBars"; 
    namedWindow(trackbarWindowName, WINDOW_NORMAL); 
    createTrackbar("l_MIN", trackbarWindowName, &l_MIN, l_MAX, on_trackbar); 
    createTrackbar("l_MAX", trackbarWindowName, &l_MAX, l_MAX, on_trackbar); 
    createTrackbar("a_MIN", trackbarWindowName, &a_MIN, a_MAX, on_trackbar); 
    createTrackbar("a_MAX", trackbarWindowName, &a_MAX, a_MAX, on_trackbar); 
    createTrackbar("b_MIN", trackbarWindowName, &b_MIN, b_MAX, on_trackbar); 
    createTrackbar("b_MAX", trackbarWindowName, &b_MAX, b_MAX, on_trackbar); 
    createTrackbar("Erosion", trackbarWindowName, &kerode, 31, on_trackbar); 
    createTrackbar("Dilation", trackbarWindowName, &kdilate, 31, on_trackbar); 
} 

void morphit(Mat &img) 
{ 
    erode(img, img, getStructuringElement(MORPH_RECT, Size(kerode, kerode))); 
    dilate(img, img, getStructuringElement(MORPH_RECT, Size(kdilate, kdilate))); 
} 

void toggle(int key) 
{ 
    if (key == 'r') 
     showchangedframe = !showchangedframe; 
} 

私の出力は、私が欲しいもの、以下 Output

で行く、以下を作成することです:advance..muchヘルプの Desired Output

おかげで必要とされています。

+1

なぜ画像のエッジマップを抽出し、エッジマップに沿って中心ピクセルと白ピクセルの間の最小の「ユークリッド距離」をチェックしますか?最小距離のポイントは、あなたが望むものを与えるでしょう。正確には、ピクセル単位でポイントを移動する必要があります(上/下/左/右)。 @RickM。 –

+1

または、移動する方向を把握するのではなく、輪郭を見つける前に画像を拡大します。 – beaker

+0

@RickM。アドバイスをいただきありがとうございます。申し訳ありませんが、どのように私はエッジマップを抽出することをお勧めしますか? – IzaMA

答えて