2012-10-26 11 views
7

Mam RotatedRect, chcę zrobić trochę przetwarzania obrazu w obróconym regionie (powiedzmy wyodrębnić histogram kolorów). Jak mogę uzyskać ROI? Mam na myśli region (piksele), aby móc przetwarzać.RotatedRect ROI w OpenCV

Znajduję this, ale zmienia region za pomocą getRotationMatrix2D i warpAffine, więc nie działa w mojej sytuacji (muszę przetworzyć oryginalne piksele obrazu).
Następnie uważam, że this sugeruje używanie maski, co brzmi rozsądnie, ale czy ktoś może nauczyć mnie jak uzyskać maskę jako zielony RotatedRect poniżej.
The green RotatedRect is the ROI I want to do some processing

Z wyjątkiem maski, czy są jakieś inne rozwiązania?
Dzięki za podpowiedź

+1

nie [to], (http://stackoverflow.com/questions/9082204/opencv-draw-a-white- fill-polygon) help? Wystarczy użyć fillPoly, aby narysować obróconego recta.Możesz uzyskać 4 punkty ograniczające go za pomocą jego rozmiaru i kąta – Hammer

Odpowiedz

7

Oto moje rozwiązanie, wykorzystujące maskę:
Pomysł jest skonstruowanie Mat mask przypisując 255 do mojego RotatedRect ROI.

Jak sprawdzić, który punkt jest w ROI (który powinien być przypisany do 255)?
Używam następującej funkcji isInROI do rozwiązania problemu.

/** 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; 
} 

Jak skonstruować maskę?
Korzystanie z poniższego kodu.

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; 
     } 
    } 
} 

Done,
vancexu

+0

Co to są wierzchołki? W moim przypadku mam współrzędne roi jako tablicę punktów_w prostym Point2f. –

1

Jeśli potrzebujesz superszybkie rozwiązanie, proponuję:

  • upraw rect załączając swoje RotatedRect rr.
  • obróć + przetłumaczyć przycięty obraz tak, aby obiekt RotatedRect był teraz odpowiednikiem elementu Rect. (używając warpAffine na iloczyn rotacji i macierzy 3x3 translacji)
  • Zachowaj ten obraz z obróconym opadem (roi=Rect(Point(0,0), rr.size())).

Pisanie jest nieco czasochłonne, ponieważ trzeba obliczyć kombinowaną transformację afiniczną.

1

Jeśli nie dbają o prędkości i chcesz stworzyć szybki prototyp dowolnego kształtu regionu, można użyć funkcji pointPolygonTest OpenCV(), która zwraca wartość dodatnią, jeżeli punkt wewnątrz:

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

Prosty kod:

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; 
3

znalazłem następujące po bardzo przydatna do tego samego. http://answers.opencv.org/question/497/extract-a-rotatedrect-area/

Jedyne zastrzeżenie to (a) zakłada się, że "kąt" to obrót wokół środka całego obrazu (nie obwiedni) i (b) w ostatniej linii poniżej (myślę) "rect.środek”należy przeprowadzić w obróconym obrazu (przy zastosowaniu macierzy rotacji).

// 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);