Ask Your Question
1

Changing the perspective using Opencv

asked 2013-08-12 02:13:41 -0600

engine gravatar image

updated 2013-08-12 15:55:02 -0600

I'm working on a project, in which I use a chessboard, the problem that I'm facing, is when I recognize the board I want to crop the part of the frame that contains it and put it "straight", for that I'm using the cv::warpPerspective function, bellow is my code and the result that I get :

int main (){
    cv::Size board(6,4);
    cv::Mat src,result,quad,transformationMatrix;
    std::vector<cv::Point2f> imageCorners;
    std::vector<cv::Point2f> top, bot;



  std::vector<cv::Point2f> not_a_rect_shape;
    cv::VideoCapture cap(0);
    char fileName[20] = "MYROI";
    int index =0;
    int key = 0 ;   
    cap >> src;
    while ( key != 27){
        cap >> src;
        if(cv::findChessboardCorners(src,board,imageCorners,CV_CALIB_CB_FILTER_QUADS)){
            int xMin =imageCorners.at(0).x  ,xMax = imageCorners.at(0).x; 
            int yMin = imageCorners.at(0).y, yMax =imageCorners.at(0).y;
        for (int i  = (imageCorners.size()-1) ; i>0;i--){
                if(xMin > imageCorners.at(i-1).x)
                        xMin = imageCorners.at(i-1).x;
                if(xMax < imageCorners.at(i-1).x)
                    xMax = imageCorners.at(i-1).x;
                if(yMin > imageCorners.at(i-1).y)
                    yMin = imageCorners.at(i-1).y;
                if(yMax < imageCorners.at(i-1).y)
                    yMax = imageCorners.at(i-1).y;
            } 
        cv::Rect  myroi(xMin-5,yMin-5,(xMax-xMin)+5,(yMax-yMin)+5);
        if ( myroi.area() > 0){
            cv::imshow("ROI",(src)(myroi));  
        result = (src)(myroi);
        not_a_rect_shape.clear();
        not_a_rect_shape.push_back(imageCorners[0]);
        not_a_rect_shape.push_back(imageCorners[board.height-1]);
        not_a_rect_shape.push_back(imageCorners[board.area()-board.height-1]);
        not_a_rect_shape.push_back(imageCorners[board.area()-1]);
        std::vector<cv::Point2f> approx;
        cv::approxPolyDP(cv::Mat(not_a_rect_shape),approx,cv::arcLength(cv::Mat(not_a_rect_shape),true)*0.02,true);
        if (approx.size()!=4){
            std::cout << " Not quadrilateral!"<<std::endl;

            not_a_rect_shape.clear();
            approx.clear();

            not_a_rect_shape.push_back(imageCorners[0]);
            not_a_rect_shape.push_back(imageCorners[board.width-1]);
            not_a_rect_shape.push_back(imageCorners[board.area()-board.width-1]);
            not_a_rect_shape.push_back(imageCorners[board.area()-1]);
            cv::approxPolyDP(cv::Mat(not_a_rect_shape),approx,cv::arcLength(cv::Mat(not_a_rect_shape),true)*0.02,true); 
        }

        // center 
        cv::Point2f center(0,0);
        for (int i = 0 ; i <not_a_rect_shape.size(); i++)
                center+= not_a_rect_shape[i];
            center *=( 1./not_a_rect_shape.size()); // the center position 

            top.clear();
            bot.clear();
        // ordering  the  4 points 
        for (int i = 0; i < not_a_rect_shape.size(); i++){
            if (not_a_rect_shape[i].y < center.y)
                top.push_back(not_a_rect_shape[i]);
            else
                 bot.push_back(not_a_rect_shape[i]);
            }
        std::cout << center << std::endl;
        if(top.size()== 2 && bot.size()==2){ 
            cv::Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
            cv::Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
            cv::Point2f bl = bot[0].x > bot[1].x ? bot[1] : bot[0];
            cv::Point2f br = bot[0].x > bot[1].x ? bot[0] : bot[1];
            not_a_rect_shape.clear();
            not_a_rect_shape.push_back(tl);
            not_a_rect_shape.push_back(tr);
            not_a_rect_shape.push_back(br);
            not_a_rect_shape.push_back(bl);

            // Define the destination image
            quad = cv::Mat::zeros(300, 220, CV_8UC3);
            //quad = cv::Mat::zeros(result.rows,result.cols,CV_8UC3);
        // Corners of the destination image
            std::vector<cv::Point2f> quad_pts;
            quad_pts.push_back(cv::Point2f(0, 0));
            quad_pts.push_back(cv::Point2f(quad.cols, 0));
            quad_pts.push_back(cv::Point2f(quad.cols, quad.rows));
            quad_pts.push_back(cv::Point2f(0, quad.rows));
            transformationMatrix= cv ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2013-08-12 05:35:07 -0600

engine gravatar image

I've asked the same question on stackoverflow and I got an answer for those who need it : http://stackoverflow.com/questions/18181012/changing-the-perspective-using-opencv

edit flag offensive delete link more

Comments

1

Please accept your own answer, therefor the question could be mark as "correct" to help other, and to keep the forum the more clear it could be. Thanks. By the way, it's nice to you to report the solution here, thanks!

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2013-08-12 17:39:44 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-08-12 02:13:41 -0600

Seen: 361 times

Last updated: Aug 12 '13