2012-10-26 23 views
7

Ho un RotatedRect, voglio fare un po 'di elaborazione delle immagini nella regione ruotata (ad esempio, estrarre l'istogramma di colore). Come posso ottenere il ROI? Voglio dire ottenere la regione (pixel) in modo che io possa fare l'elaborazione.ROOT RotatedRect in OpenCV

Io trovo this, ma cambia la regione utilizzando getRotationMatrix2D e warpAffine, quindi non funziona per la mia situazione (ho bisogno di elaborare i pixel dell'immagine originale).
Quindi trovo che lo this suggerisce di usare la maschera , che suona ragionevole, ma qualcuno può insegnarmi come ottenere la maschera come la RotatedRect verde di seguito.
The green RotatedRect is the ROI I want to do some processing

Eccezioni per la maschera, esistono altre soluzioni?
Grazie per qualsiasi suggerimento

+1

fa [questo] (http://stackoverflow.com/questions/9082204/opencv-draw-a-white- poligono pieno) aiuto? Hai solo bisogno di usare fillPoly per disegnare il tuo rect ruotato.Puoi ottenere i 4 punti delimitati usando le sue dimensioni e l'angolo. – Hammer

risposta

7

Ecco la mia soluzione, utilizzando maschera:
l'idea è costruire un Mat mask assegnando 255 al mio RotatedRect ROI.

Come sapere quale punto è in ROI (che dovrebbe essere assegnato a 255)?
Io uso la seguente funzione isInROI per risolvere il problema.

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

come costruire il maschera?
Utilizzando il seguente codice.

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

Cosa sono i vertici? Nel mio caso, ho le coordinate di roi come array rect_points di Point2f. –

1

Se avete bisogno di una soluzione superveloce, suggerisco:

  • raccolto un rettangolo che racchiude il tuo RotatedRect rr.
  • ruota + converte indietro l'immagine ritagliata in modo che RotatedRect ora sia equivalente a un Rett. (usando warpAffine sul prodotto della rotazione e le matrici di traduzione 3x3)
  • Mantiene quel ROI dell'immagine ruotata indietro (roi=Rect(Point(0,0), rr.size())).

È un po 'dispendioso in termini di tempo scrivere perché è necessario calcolare la trasformazione affine combinata.

1

Se non vi interessa circa la velocità e si desidera creare un prototipo veloce per qualsiasi forma della regione, è possibile utilizzare un pointPolygonTest funzione di OpenCV(), che restituisce un valore positivo se il punto interno:

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

codice semplice:

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

ho trovato il seguente post molto utile per fare lo stesso. http://answers.opencv.org/question/497/extract-a-rotatedrect-area/

Le uniche avvertimenti sono che (a) "angolo" qui viene considerata una rotazione attorno al centro dell'intera immagine (non il riquadro) e (b) nell'ultima riga sottostante (Credo) "rect.centro" deve essere trasformato dell'immagine ruotata (applicando la matrice di rotazione).

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