4

正方形を含む画像があり、その正方形に含まれる領域を抽出する必要があります。squares.cスクリプト(すべてのOpenCVディストリビューションのサンプルで利用可能)を適用した後、正方形のベクトルを取得し、それぞれの画像を保存する必要があります。

ユーザーkarlphillipはこれを提案しました:

for (size_t x = 0; x < squares.size(); x++) 
{
    Rect roi(squares[x][0].x, squares[x][0].y, 
             squares[x][1].x - squares[x][0].x, 
             squares[x][3].y - squares[x][0].y);
    Mat subimage(image, roi);
}

元の画像で検出されたすべての正方形のサブ画像と呼ばれる新しいマットを生成するため

karlが私を思い出したように、画像で検出された点は完全な正方形を表していない可能性があります(上の画像でわかるように)が、私があなたに提案したコードはそれらがそうであると仮定しています。

実際、私はこのエラーを受け取ります:

OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width &&
      roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height &&
      roi.y + roi.height <= m.rows) in Mat, file /usr/include/opencv/cxmat.hpp, 
      line 187

terminate called after throwing an instance of 'cv::Exception'
what():  /usr/include/opencv/cxmat.hpp:187: error: (-215) 0 <= roi.x && 
       0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y &&
       0 <= roi.height && roi.y + roi.height <= m.rows in function Mat

Aborted

スクリプトに非完全な正方形も受け入れさせるための提案はありますか?

4

1 に答える 1

11

そのコードについていくつか明確にする必要があるように感じます。

まず、検出された領域が完全な正方形であると想定します。これは、内部のポイントの一部を無視しsquares[x]て新しいを作成するためMatです。

次にp0、領域を構成するポイントが、画像の左上隅から時計回りに検出されたと想定します。

(p0)  1st----2nd  (p1)
       |      |
       |      |
(p3)  4th----3rd  (p2)

これは、検出されたすべての領域に当てはまるとは限りません。つまり、このコードは次のとおりです。

Rect roi(squares[x][0].x, squares[x][0].y, 
         squares[x][1].x - squares[x][0].x, 
         squares[x][3].y - squares[x][0].y);

おそらく、負の幅や高さの値など、無効な寸法のROIが生成されるため、OpenCVはにをスローcv::ExceptionしますMat subimage(image, roi);

あなたがすべきことは、リージョンの左上のポイントを識別してそれを呼び出すコードを記述しp0、次に右側の最も近い隣のポイントを記述し、p1次にリージョンの右下のポイントを見つけてそれを呼び出すことp2です。残っているのはですp3。この後、ROIの組み立ては簡単です。

Rect roi(p0.x, p0.y, 
         p1.x - p0.x, 
         p3.y - p0.y);

編集

OpenCVのv2.3のドキュメントを読んでいるときに、優れた解決策を見つけました。これは、前に説明したプロセスを自動化し、物事を非常に簡単かつクリーンにします。このトリックを使用して、ベクトル内の4つのポイントを意味のある構造に並べ替えることができます。Rect

// Data returned and filled by findSquares(). Check the example squares.cpp for more info on this function.
vector<vector<Point> > squares;

for (size_t i = 0; i < squares.size(); i++)
{
    Rect rectangle = boundingRect(Mat(squares[i]));
    cout << "#" << i << " rectangle x:" << rectangle.x << " y:" << rectangle.y << " " << rectangle.width << "x" << rectangle.height << endl;
}
于 2011-10-13T14:49:14.880 に答える