2017-05-31 5 views
0

Also, ich habe ein Problem:C++ OpenCV Rescale Bounding Rect

Im opencv in Android zu tun, und da Bilder, die mit meinem Handy im, unter sehr hoher Auflösung sind, möchte ich kleinere Größe ändern Bild, erhalten Konturen und bearbeiten Sie das Bild, und erstellen Sie dann umgrenzende Rect auf dem Originalbild. Dafür müsste ich diese Bounding Box skalieren, damit sie perfekt zu meinem Originalbild passt. Der Code, den ich habe, funktioniert sehr gut mit der Verarbeitung und Zeichnung Bounding Box auf dem Originalbild, aber, wie Skalierung zu tun? Hier ist der Code-Schnipsel:

Mat &image = *(Mat *) matAddrRgba; 
//over here I should resize image and do the processing with the resized one, and in the end, scale everything back so I can draw the bounding box to the original 
    Rect bounding_rect; 

    Mat thr(image.rows, image.cols, CV_8UC1); 
    cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray 
    threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray 

    vector<vector<Point> > contours; // Vector for storing contour 
    vector<Vec4i> hierarchy; 
    RotatedRect rect; 
    findContours(thr, contours, hierarchy, CV_RETR_CCOMP, 
       CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image 
    sort(contours.begin(), contours.end(), 
     compareContourAreas);   //Store the index of largest contour 
    bounding_rect = boundingRect(contours[0]); 
    rect = minAreaRect(contours[0]); 
    // matrices we'll use 
    Mat rot_mat, rotated; 
    // get angle and size from the bounding box 
    float angle = rect.angle; 
    Size rect_size = rect.size; 

    if (rect.angle < -45.) { 
     angle += 90.0; 
     swap(rect_size.width, rect_size.height); 
    } 

    rot_mat = getRotationMatrix2D(rect.center, angle, 1); 

    warpAffine(image, rotated, rot_mat, image.size(), INTER_CUBIC); 

    image = rotated; 

    cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray 
    threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray 

    findContours(thr, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); 
    sort(contours.begin(), contours.end(), compareContourAreas); 
    bounding_rect = boundingRect(contours[0]); 

    image = Mat(image, bounding_rect); 
+0

"Wie skaliere ich?" - Wenn es sich nicht um das Klettern oder Entfernen von Schuppen von Objekten handelt, dann tendiert * Multiplikation * dazu, den Trick zu machen. Sie können der neuen Breite und Höhe einen Versatz von "Maßstab 1" hinzufügen, um ihn etwas besser anzupassen. Nimm einfach ein Stück Papier und zeichne es - das sollte nicht viel Arbeit in Anspruch nehmen. –

+0

@ DanMašek Ich bekomme das gedrehte Rechteck, das ist das Produkt meiner Berechnungen. Ich drehe dann das Bild, um es perfekt auf mein Gerät auszurichten. Danach schneide ich mit dem gedrehten Rect (erzeugt ein begrenzendes Rechteck). Wie erweitern/multiplizieren/vergrößern Sie das umgebende Rechteck? –

+0

Wenn Sie zum Beispiel die Breite und Höhe eines Bildes verdoppeln, gelten die gleichen Skalierungsfaktoren für Koordinaten. Die X- und Y-Koordinaten der Bounding Box würden sich also verdoppeln, Breite und Höhe würden sich verdoppeln. –

Antwort

2

Ok, so würde ich mit diesem beginnen:

Mat &img = (Mat) matAddrRgba; 
    Mat image; 
    double thrA = 5; 
    resize(img, image, Size((int) (img.size().width/thrA), (int) (img.size().height/thrA))); 

    Rect bounding_rect; 

    Mat thr(image.rows, image.cols, CV_8UC1); 
    cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray 
    threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray 

    vector<vector<Point> > contours; // Vector for storing contour 
    vector<Vec4i> hierarchy; 
    RotatedRect rect; 
    findContours(thr, contours, hierarchy, CV_RETR_CCOMP, 
       CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image 
    sort(contours.begin(), contours.end(), 
     compareContourAreas);   //Store the index of largest contour 
    bounding_rect = boundingRect(contours[0]); 

    bounding_rect.width = (int) (bounding_rect.width * thrA); 
    bounding_rect.height = (int) (bounding_rect.height * thrA); 
    bounding_rect.x = (int) (bounding_rect.x * thrA); 
    bounding_rect.y = (int) (bounding_rect.y * thrA); 

    rectangle(img, bounding_rect, Scalar(0, 172, 236, 255), 3); 

Wie Sie sehen können, sollten Sie eine Skala haben, dass Skala sollte mit Breite, Höhe multipliziert werden , x und y des begrenzenden Rect. Sie können den Rest davon herausfinden.