8

私はRotatedRect回転した領域でいくつかの画像処理を行いたいです(たとえば、色ヒストグラムを抽出します)。ROI を取得するにはどうすればよいですか? 私は処理を行うことができるように領域(ピクセル)を取得することを意味します。

これは見つかりましgetRotationMatrix2Dたが、 と を使用して領域を変更するwarpAffineため、私の状況では機能しません (元の画像ピクセルを処理する必要があります)。
次に、これはmaskを使用することを示唆していますが、これは合理的に聞こえますが、下の緑の RotatedRect としてマスクを取得する方法を誰かに教えてもらえますか?
緑色の RotatedRect は、処理したい ROI です。

マスクを除いて、他の解決策はありますか?
ヒントをありがとう

4

4 に答える 4

7

maskを使用した私の解決策は次のとおり
です。Mat maskRotatedRect ROI

ROI (255 に割り当てる必要があります) 内のどのポイントを知るには? 問題に対処する
ために、次の関数を使用します。isInROI

/** decide whether point p is in the ROI.
*** The ROI is a rotated rectange whose 4 corners are stored in roi[] 
**/
bool isInROI(Point p, Point2f roi[])
{
    double pro[4];
    for(int i=0; i<4; ++i)
    {
        pro[i] = computeProduct(p, roi[i], roi[(i+1)%4]);
    }
    if(pro[0]*pro[2]<0 && pro[1]*pro[3]<0)
    {
        return true;
    }
    return false;
}

/** function pro = kx-y+j, take two points a and b,
*** compute the line argument k and j, then return the pro value
*** so that can be used to determine whether the point p is on the left or right
*** of the line ab
**/
double computeProduct(Point p, Point2f a, Point2f b)
{
    double k = (a.y-b.y) / (a.x-b.x);
    double j = a.y - k*a.x;
    return k*p.x - p.y + j;
}

マスクの作り方は?
次のコードを使用します。

Mat mask = Mat(image.size(), CV_8U, Scalar(0));
for(int i=0; i<image.rows; ++i)
{
    for(int j=0; j<image.cols; ++j)
    {
        Point p = Point(j,i);   // pay attention to the cordination
        if(isInROI(p,vertices))
        {
            mask.at<uchar>(i,j) = 255;
        }
    }
}

やった、
ヴァンセクス

于 2012-10-31T06:29:43.320 に答える
5

同じことを行うには、次の投稿が非常に役立つことがわかりました。 http://answers.opencv.org/question/497/extract-a-rotatedrect-area/

唯一の注意点は、(a) ここでの「角度」は、(バウンディング ボックスではなく) 画像全体の中心を中心とした回転であると想定されていることと、(b) 下の最後の行 (私が思うに) 「rect.center」であることです。回転した画像に変換する必要があります (回転行列を適用することにより)。

    // rect is the RotatedRect 
    RotatedRect rect;
    // matrices we'll use
    Mat M, rotated, cropped;
    // get angle and size from the bounding box
    float angle = rect.angle;
    Size rect_size = rect.size;
    // thanks to http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/
    if (rect.angle < -45.) {
        angle += 90.0;
        swap(rect_size.width, rect_size.height);
    }
    // get the rotation matrix
    M = getRotationMatrix2D(rect.center, angle, 1.0);
    // perform the affine transformation
    warpAffine(src, rotated, M, src.size(), INTER_CUBIC);
    // crop the resulting image
    getRectSubPix(rotated, rect_size, rect.center, cropped);
于 2014-04-25T20:54:40.010 に答える
1

超高速のソリューションが必要な場合は、次のことをお勧めします。

  • RotatedRect を囲む Rect をトリミングします rr
  • RotatedRect が Rect と同等になるように、トリミングされた画像を回転 + 変換して戻します。(回転と平行移動の 3x3 行列の積に warpAffine を使用)
  • 逆回転した画像の ROI を保持します ( roi=Rect(Point(0,0), rr.size()))。

ただし、結合されたアフィン変換を計算する必要があるため、記述するには少し時間がかかります。

于 2012-11-26T21:08:51.923 に答える
1

速度を気にせず、領域の任意の形状に対して高速なプロトタイプを作成したい場合は、openCV 関数 pointPolygonTest() を使用できます。これは、ポイントが内部にある場合に正の値を返します。

double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)

簡単なコード:

vector<Point2f> contour(4);
contour[0] = Point2f(-10, -10);
contour[1] = Point2f(-10, 10);
contour[2] = Point2f(10, 10);
contour[3] = Point2f(10, -10);    
Point2f pt = Point2f(11, 11);
an double res = pointPolygonTest(contour, pt, false);
if (res>0)
    cout<<"inside"<<endl;
else
    cout<<"outside"<<endl;
于 2014-02-06T23:56:57.740 に答える