1

私は、iPhoneのカメラを使ってテレビ画面を検出しています。現在のアプローチは、ピクセルごとに後続のフレームを比較し、累積差を追跡することです。結果は画像に示されているように2値画像です。 Original imageカメラを使ったOpenCV検出画面

私にとっては、これは長方形のように見えますが、OpenCVではそうは思われません。その側面は完全に真っ直ぐではなく、時には検出を困難にするためにさらに色のにじみがあります。 OpenCVに慣れていないので、矩形を検出しようとしているOpenCVコードです。

uint32_t *ptr = (uint32_t*)CVPixelBufferGetBaseAddress(buffer); 
cv::Mat image((int)width, (int)height, CV_8UC4, ptr); // unsigned 8-bit values for 4 channels (ARGB) 

cv::Mat image2 = [self matFromPixelBuffer:buffer]; 

std::vector<std::vector<cv::Point>>squares; 

// blur will enhance edge detection 

cv::Mat blurred(image2); 
GaussianBlur(image2, blurred, cvSize(3,3), 0);//change from median blur to gaussian for more accuracy of square detection 

cv::Mat gray0(blurred.size(), CV_8U), gray; 

std::vector<std::vector<cv::Point> > contours; 

// find squares in every color plane of the image 
for (int c = 0; c < 3; c++) { 
    int ch[] = {c, 0}; 
    mixChannels(&blurred, 1, &gray0, 1, ch, 1); 

    // try several threshold levels 
    const int threshold_level = 2; 
    for (int l = 0; l < threshold_level; l++) { 
     // Use Canny instead of zero threshold level! 
     // Canny helps to catch squares with gradient shading 
     if (l == 0) { 
      Canny(gray0, gray, 10, 20, 3); // 

      // Dilate helps to remove potential holes between edge segments 
      dilate(gray, gray, cv::Mat(), cv::Point(-1,-1)); 
     } else { 
      gray = gray0 >= (l+1) * 255/threshold_level; 
     } 

     // Find contours and store them in a list 
     findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); 

     // Test contours 
     std::vector<cv::Point> approx; 
     int biggestSize = 0; 
     for (size_t i = 0; i < contours.size(); i++) { 
      // approximate contour with accuracy proportional 
      // to the contour perimeter 
      approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true); 
      if (approx.size() != 4) 
       continue; 

      // Note: absolute value of an area is used because 
      // area may be positive or negative - in accordance with the 
      // contour orientation 
      int areaSize = fabs(contourArea(cv::Mat(approx))); 
      if (approx.size() == 4 && areaSize > biggestSize) 
       biggestSize = areaSize; 
      cv::RotatedRect boundingRect = cv::minAreaRect(approx); 
      float aspectRatio = boundingRect.size.width/boundingRect.size.height; 

      cv::Rect boundingRect2 = cv::boundingRect(approx); 
      float aspectRatio2 = (float)boundingRect2.width/(float)boundingRect2.height; 

      bool convex = isContourConvex(cv::Mat(approx)); 
      if (approx.size() == 4 && 
       fabs(contourArea(cv::Mat(approx))) > minArea && 
       (aspectRatio >= minAspectRatio && aspectRatio <= maxAspectRatio) && 
       isContourConvex(cv::Mat(approx))) { 
       double maxCosine = 0; 

       for (int j = 2; j < 5; j++) { 
        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1])); 
        maxCosine = MAXIMUM(maxCosine, cosine); 
       } 
       double area = fabs(contourArea(cv::Mat(approx))); 
       if (maxCosine < 0.3) { 
        squares.push_back(approx); 
       } 
      } 
     } 
    } 

はキャニー・ステップの後の画像は、それは私には罰金だが、何らかの理由矩形のために検出されないこの Image after Canny-step のように見えます。私のパラメータに間違ったことがあれば誰でも説明できますか?

私の2番目のアプローチは、基本的に上記と同じコードを使用してOpenCV Houghライン検出を使用することでした。Canny画像に対しては、次にHoughLines関数を呼び出します。私は垂直線を検出するためにしきい値を低くしなければならないので、私にはかなりの数の線があります。結果の行はこのようなものです:

Hough lines

問題は、いくつかの多くの行があるということです。最初の画像に示されているように、青い矩形の辺に接触している線を見つけるにはどうすればよいですか?

また、画面を検出する優れた方法はありますか?

答えて

0

まず、最大面積の輪郭を見つけてreferenceを見つけ、次に最小面積の矩形referenceを作成し、輪郭領域を矩形領域に分割します。これはあなたの輪郭と矩形になります。

+0

返信ありがとう、非常に巧妙なアプローチ。これを実装しましたが、結果として得られる長方形が大きすぎます。色のにじみがあるすべての領域が含まれます。私はコーナーを正確に検出する必要があります。 – superg

関連する問題