2013年12月26日 星期四

OpenCV: Cropping a ROI(Regions of Interest) out of an Image

since: 2013/12/26
update: 2013/12/26

reference:
1. Amazon.com: Practical OpenCV eBook
2. Welcome to opencv documentation!
3. I touchs: Using OpenCV on Mac OS X

A. 前置作業:
     1. 先依照 I touchs: Using OpenCV on Mac OS X 的說明, 建置好開發環境.

     2. 需要加入到專案的 OpenCV 函式庫爲: (Add Files to Project...)
          libopencv_core.dylib
          libopencv_highgui.dylib
          libopencv_imgproc.dylib

     3. 將 main.cpp 的 main function 更名.(不作為程式執行的進入點)
          //int main(int argc, const char * argv[])  
          int main_main(int argc, const char * argv[])

     4. 爲專案新增 C++ 檔案:      
         點選專案 > New File... > OS X > C and C++ > C++ Class > Next >
         Save as: ROICropping.cpp > Create

----------------------------------------------------------------------------------------

B. 撰寫程式:
    1. 開啓 ROICropping.h 檔案, 修改如下:
#ifndef __HelloOpenCV__ROICropping__
#define __HelloOpenCV__ROICropping__

#include <iostream>
//@add
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>


#endif /* defined(__HelloOpenCV__ROICropping__) */

---------------------------------------------------------------------------------

    2. 開啓 ROICropping.cpp 檔案, 修改如下:
#include "ROICropping.h"

//@add
using namespace std;
using namespace cv;


bool ldown = false;
// left mouse button down flag
bool lup = false; // left mouse button up flag

Mat img; // original image
Mat croppedImage; // cropped image
Point corner1, corner2; // Starting and ending of the user's selection point
Rect box; // (ROI)Regions of Interest

// Callback function for mouse events
static void mouse_callback(int event, int x, int y, int, void*)
{

    // when left mouse button is pressed
    if (event == EVENT_LBUTTONDOWN) {
        ldown = true;

        // record its position and save it in corner1
        corner1.x = x;
        corner1.y = y;
        cout << "Corner 1 recorded at " << corner1 << endl;
    }

    // when left mouse button is released
    if (event == EVENT_LBUTTONUP) {
        // if user selection is bigger than 20 piexels
        if (abs(x - corner1.x) > 20 && abs(y - corner1.y) > 20) {
            lup = true;

            // record its position and save it in corner1
            corner2.x = x;
            corner2.y = y;
            cout << "Corner 2 recorded at " << corner2 <<  endl << endl;
        }
        else
        {
            cout << "Please select a bigger region" << endl;
            ldown = false;
        }
    }

    // update the box showing the selected region as the user drags the mouse
    if (ldown == true && lup == false) {
        Point pt;
        pt.x = x;
        pt.y = y;
        Mat local_img = img.clone();
        rectangle(local_img, corner1, pt, Scalar(0, 0, 255)); // b, g, r
        imshow("Cropping app", local_img);
    }

    // Define ROI and crop it out when both corners have been selected
    if (ldown == true && lup == true) {
        box.width = abs(corner1.x - corner2.x); // 2 個 corner X 軸座標距離的絕對值

        box.height = abs(corner1.y - corner2.y); // 2 個 corner Y 軸座標距離的絕對值
        box.x = min(corner1.x, corner2.x); // 2 個 corner X 軸座標的最小值
        box.y = min(corner1.y, corner2.y); // 2 個 corner Y 軸座標的最小值
       
        // Make a image out of just the selected ROI and display it in a new window
        Mat crop(img, box);
        namedWindow("Crop");
        imshow("Crop", crop);

       
        // clone the cropped image(ROI) and save it to a file
        croppedImage = img(box).clone();
        imwrite("/Lanli/RD/Projects/OpenCV_Mac/HelloOpenCV/pipi_cropped.png", croppedImage);
       
        ldown = false;
        lup = false;
    }
}

int main()
{

    // Read image
    img = imread("/Lanli/RD/Projects/OpenCV_Mac/HelloOpenCV/pipi.png");
    namedWindow("Cropping app");
    imshow("Cropping app", img);
   
    setMouseCallback("Cropping app", mouse_callback);
   
    while (char(waitKey(1) != 'q')) {
    }
   
    return 0;
}


----------------------------------------------------------------------------------------

C. 執行結果:
     Cropping:

     Saving:

6 則留言:

  1. Thank you very much, you're the man! You saved our time :)

    回覆刪除
  2. You're welcome! Glad to help somebody little busy ^^

    回覆刪除
  3. 很棒的文章,我照著做也成功了。我想用haarcascade_mcs_upperbody.xml從照片中辨識出上半身,並設定固定的長寬比(例如3:2),要如何寫呢?謝謝。

    回覆刪除
  4. 您好. 謝謝! 最近沒有在碰這方面的東西, 不好意思~

    回覆刪除
  5. You really helped, with your help my Electronic project is more easier :)

    回覆刪除

注意:只有此網誌的成員可以留言。