2017-03-12 5 views
1

私が取り組んでいるプロジェクトのフィードバックが必要です。基本的には、カメラからのビデオストリームから矩形を追跡する必要があります。私はそうするためにC++用のOpenCVライブラリを使用しています。 まず、色の検出を適用しました(一度に1色のみを追跡する必要があります)。その後、フィルタ処理された画像の輪郭を取得するために、Cannyエッジ検出を適用しました。この時点で、矩形があるかどうかを判断できるはずです。(x、y)平面内の位置です(その中心または頂点の位置があまりにも大きな違いではないことを知っています)そのような平面に関して。 これは、信号がカメラから来ているので、ストリームに表示されているシェイプのこれらの機能を追跡できる必要があるという意味で、「リアルタイム」で行う必要があります。カメラから長方形を検出する

これは、このような場合に誰がそれを必要とするコードであるキャニーエッジ検出アルゴリズムによって検出され、

閾値化色の選択後の入力のバージョン(左)とその輪郭の写真である。

#include <sstream> 
#include <string> 
#include <iostream> 
#include <opencv/highgui.h> 
#include <opencv/cv.h> 

#define HIGH_CANNY_THRESH 255 
#define CANNY_KERNEL_SIZE 3 
#define  FRAME_WIDTH 640 
#define  FRAME_HEIGHT 480 

#define DISPLAY_IMAGES true 

using namespace std; 
using namespace cv; 

void createTrackbarsForHSVSel(); 
void morphOps(Mat &thresh); 

int LOW_H = 0; 
int HIGH_H = 255; 
int LOW_S = 0; 
int HIGH_S = 255; 
int LOW_V = 0; 
int HIGH_V = 255; 

int LOW_THRESHOLD = 0; 
int HIGH_THRESHOLD = 100; 

int  CORNER_THRESH = 200; 
int MAX_CORNER_THRESH = 255; 

int main(int argc, char* argv[]) 
{ 

    Mat src, hsvSpace, threshold, edges; 

    vector<vector<Point> > contours; // Vectors for the contours storage 
    vector<Vec4i> hierarchy; 

    createTrackbarsForHSVSel(); // create trackbars for the HSV palette 
    createTrackbar("Min Threshold", "Trackbars", &LOW_THRESHOLD , HIGH_THRESHOLD); 
    createTrackbar("Max Threshold", "Trackbars", &HIGH_THRESHOLD, HIGH_THRESHOLD); 

    VideoCapture capture; 
    capture.open(0); 

    printf("Starting to capture from camera0:\nisOpened = %d\n", capture.isOpened()); 

    capture.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH); 
    capture.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT); 

    while(1) // loop exectues as long as the user doesn't press ESC, q or Q 
    { 
     capture.read(src); // read from camera 
     cvtColor(src, hsvSpace, CV_BGR2HSV); // RGB to HSV color space transformation 
     // create a binary such that 1s are between Scalar(min_, min_, min_) and Scalar(max_, max_, max_) 
     inRange(hsvSpace, Scalar(LOW_H, LOW_S, LOW_V), Scalar(HIGH_H, HIGH_S, HIGH_V), threshold); 
     morphOps(threshold); // morphological operations: they allow to close the 'hole' and delete the 'dots' 

     // threshold now contains the binary that only displays one colour (if the trackbars are set correctly) 

     // Apply Gaussian blurring and Canny edge algorithm for the edge detection 
     GaussianBlur(threshold, threshold, Size(3,3), 0, 0); // Kernel = 3x3, Sigmas are calculated automatically (see 'getGaussianKernel()') 
     Canny(threshold, edges, LOW_THRESHOLD, HIGH_THRESHOLD); 

     /* 
     Algorithm that approximates the edges of the figure to a rectangle. 
     After that it needs to be able to calculate the rectangle position and orientation 
     (will something like RotatedRect be useful?) 
     */ 

     #if DISPLAY_IMAGES == true 
     // Show images 
     imshow("Camera feed", src); 
     imshow("Thresholded", threshold); 
     imshow("Edges", edges); 
     #endif 

     if((char)waitKey(30) == 'q') 
     break; 
    } 

    return 0; 
} 

void createTrackbarsForHSVSel() 
{ 
    namedWindow("Trackbars", CV_WINDOW_AUTOSIZE); 

    createTrackbar("Low hue", "Trackbars", &LOW_H , HIGH_H); 
    createTrackbar("High hue", "Trackbars", &HIGH_H, HIGH_H); 
    createTrackbar("Low sat", "Trackbars", &LOW_S , HIGH_S); 
    createTrackbar("High sat", "Trackbars", &HIGH_S, HIGH_S); 
    createTrackbar("Low val", "Trackbars", &LOW_V , HIGH_V); 
    createTrackbar("High val", "Trackbars", &HIGH_V, HIGH_V); 

    return; 
} 

void morphOps(Mat &thresh) 
{ 
    // create structuring element that will be used to "dilate" and "erode" image. 
    // the element chosen here is a 3px by 3px rectangle. 
     // As a rule of thumb you want to dilate with larger element to make sure the object is nicely visible 

    erode (thresh,thresh,getStructuringElement(MORPH_RECT, Size(3,3))); 
     dilate(thresh,thresh,getStructuringElement(MORPH_RECT, Size(3,3))); 

    dilate(thresh,thresh,getStructuringElement(MORPH_RECT, Size(3,3))); 
    erode (thresh,thresh,getStructuringElement(MORPH_RECT, Size(3,3))); 

    return ;  
} 

ありがとうございました!

+0

ハフ変換を考えましたか?私は円を検出するために使用されましたが、理論上のあらゆる形状に適用可能です – alangab

+0

交差するハフ線は、矩形/四角を生成する可能性があります –

+0

そして、どこに問題がありますか? Beacuse私はNotSureです。 – m3h0w

答えて

0

サンプルに表示されているように、矩形がしきい値処理後に定義されている場合、これはかなり基本的な作業です。

  1. findContours()を使用して、四角形をポイントのセットとして取得します。
  2. 使用minAreaRect()は向きが同じままことを確認してください(輪郭の周りに四角形を描画する
  3. 場合にfind only rectanglesにいることを確認し、将来的にいくつかのノイズがあります
  4. MinAreaRectが既にあなたが必要なすべての情報で構成されています。。(x,y), (width, height), thetaあなたは非効率的な何かをコーディングした場合。。リアルタイムで何の問題も動作しないはず

。あなたは角度は奇妙なことで怒っ行く前にthisをチェックアウトすることを忘れないでください、それは、単に処理ごとに2または3を行いません。フレーム。

+0

Cannyアルゴリズムの後、私はfindContoursを使用し、その後、私はminAreaRectアルゴリズムを実装する関数を作成しました。私はそれをより良くするためにいくつかのことを調整する必要があります。どうもありがとう! – NotSure

+0

ようこそ。あなたの問題を解決した場合は、その答えを受け入れることを検討してください。がんばろう! – m3h0w