2012-01-23 10 views
5

近くの輪郭を2つ(またはそれ以上)接続する機能はありますか?私のイン/アウトプットを見て、あなたは私が何を意味するかわかります...OpenCV C++/Obj-C:近くの輪郭を接続する

マイコード:

[... some processing ...] 

// getting contours 
std::vector<std::vector<cv::Point> > contours; 
findContours(input, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 

// approximate contours 
std::vector<std::vector<cv::Point> > contours_poly(contours.size()); 
for(int i = 0; i < contours.size(); i++) { 
    approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true); 
} 

// debugging 
cv::Scalar colors[3]; 
colors[0] = cv::Scalar(255, 0, 0); 
colors[1] = cv::Scalar(0, 255, 0); 
colors[2] = cv::Scalar(0, 0, 255); 
for (int idx = 0; idx < contours_poly.size(); idx++) { 
    cv::drawContours(output, contours_poly, idx, colors[idx % 3]); 
} 

output output

+2

あなたが拡張可能性それらが十分に接近している場合には、画像を連結してください。 – Adrian

+0

iOSでどのように演奏しましたか? –

+0

これはiOSで動作しています。 https://github.com/aptogo/OpenCVForiPhoneのiOS版OpenCVのコピーを手に入れて、あなたの頭を包んでください。 – dom

答えて

8

私はちょうど全体のオブジェクトの周りにバウンディングボックスを必要とするので、私は、このソリューションを思い付いた:

[... some processing ...] 

// getting contours 
std::vector<std::vector<cv::Point> > contours; 
findContours(input, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 

// approximate contours 
std::vector<std::vector<cv::Point> > contours_poly(contours.size()); 
for(int i = 0; i < contours.size(); i++) { 
    approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true); 
} 

// merge all contours into one vector 
std::vector<cv::Point> merged_contour_points; 
for (int i = 0; i < contours_poly.size(); i++) { 
    for (int j = 0; j < contours_poly[i].size(); j++) { 
    merged_contour_points.push_back(contours_poly[i][j]); 
    } 
} 

// get rotated bounding box 
std::vector<cv::Point> hull; 
cv::convexHull(cv::Mat(merged_contour_points),hull); 
cv::Mat hull_points(hull); 
cv::RotatedRect rotated_bounding_rect = minAreaRect(hull_points); 

時々、コショウノイズを除去することは、より良い結果につながることができます:

void removePepperNoise(cv::Mat &mask) 
{ 
    for (int y=2; y<mask.rows-2; y++) { 
     uchar *pUp2 = mask.ptr(y-2); 
     uchar *pUp1 = mask.ptr(y-1); 
     uchar *pThis = mask.ptr(y); 
     uchar *pDown1 = mask.ptr(y+1); 
     uchar *pDown2 = mask.ptr(y+2); 
     pThis += 2; 
     pUp1 += 2; 
     pUp2 += 2; 
     pDown1 += 2; 
     pDown2 += 2; 

     for (int x=2; x<mask.cols-2; x++) { 
      uchar value = *pThis; // Get this pixel value (0 or 255). // Check if this is a black pixel that is surrounded by white pixels 
      if (value == 0) { 
       bool above, left, below, right, surroundings; 
       above = *(pUp2 - 2) && *(pUp2 - 1) && *(pUp2) && *(pUp2 + 1) && *(pUp2 + 2); 
       left = *(pUp1 - 2) && *(pThis - 2) && *(pDown1 - 2); 
       below = *(pDown2 - 2) && *(pDown2 - 1) && *(pDown2) && *(pDown2 + 1) && *(pDown2 + 2); 
       right = *(pUp1 + 2) && *(pThis + 2) && *(pDown1 + 2); 
       surroundings = above && left && below && right; 
       if (surroundings == true) { 
        // Fill the whole 5x5 block as white. Since we know 
        // the 5x5 borders are already white, we just need to 
        // fill the 3x3 inner region. 
        *(pUp1 - 1) = 255; 
        *(pUp1 + 0) = 255; 
        *(pUp1 + 1) = 255; 
        *(pThis - 1) = 255; 
        *(pThis + 0) = 255; 
        *(pThis + 1) = 255; 
        *(pDown1 - 1) = 255; 
        *(pDown1 + 0) = 255; 
        *(pDown1 + 1) = 255; 
        // Since we just covered the whole 5x5 block with 
        // white, we know the next 2 pixels won't be black, 
        // so skip the next 2 pixels on the right. 
        pThis += 2; 
        pUp1 += 2; 
        pUp2 += 2; 
        pDown1 += 2; 
        pDown2 += 2; 
       } 
      } 
      // Move to the next pixel on the right. 
      pThis++; 
      pUp1++; 
      pUp2++; 
      pDown1++; 
      pDown2++; 
     } 
    } 
} 
+0

驚くばかりです。できるだけこの回答を受け入れてください。その近くのチェックボックスをクリックして正式な回答として選択します。 – karlphillip

+0

@karlphillipねえ、私はそれをやろう! – dom

+0

誰でも落とした:理由を説明してください! – dom

2

単にポイントを通過し、最も近いstartpointsまたはエンドポイントを見つけますそれらを接続します。輪郭線が接続されているかどうかは、あなたのケースでは決めるのが難しいです。 Adrian Popoviciのようなmorfologyが、ポイントを接続するかどうかを決定する最大距離を指定しなければならないと言った場合、