perspective - OpenCV warpPerspective - how to know destination image size? -


ok, have admit novice opencv , matlab/lin. algebra knowledge might introducing bias. want simple, while still did not manage find answer.

when trying rectify image (or part of image) under perspective transformation, perform 2 steps (assuming have 4 points define distorted object):

  1. find transformation between perfect rectangle , distorted shape (in opencv, via findhomography() or getperspectivetransform() - why 2 operate differently on same points story, frustrating); gives matrix t.
  2. apply inverse of t distorted shape transform rectangle (in opencv, done warpperspective()).

now, last function (warpperspective()) asks user specify size of destination image.

my question how users should know beforehand size be. low-level way of doing applying transformation t corner points of image in object found, guaranteeing don't out of bounds newly transformed shape. however, if take matrix out of t , apply manually points, result looks weird.

is there way in opencv? thanks!

p.s. below code:

float leftx, lowery, rightx, highery;     float minx = std::numeric_limits<float>::max(), maxx = std::numeric_limits<float>::min(), miny = std::numeric_limits<float>::max(), maxy = std::numeric_limits<float>::min();  mat value, pt; for(int i=0; i<4; i++) {     switch(i)     {         case 0:             pt = (mat_<float>(3, 1) << 1.00,1.00,1.00);                                      break;         case 1:             pt = (mat_<float>(3, 1) << srcim.cols,1.00,1.00);             break;         case 2:             pt = (mat_<float>(3, 1) << 1.00,srcim.rows,1.00);             break;         case 3:             pt = (mat_<float>(3, 1) << srcim.cols,srcim.rows,1.00);             break;         default:             cerr << "wrong switch." << endl;             break;     }                    value = invh*pt;         value /= value.at<float>(2);             minx = min(minx,value.at<float>(0));     maxx = max(maxx,value.at<float>(0));     miny = min(miny,value.at<float>(1));     maxy = max(maxy,value.at<float>(1)); } leftx = std::min<float>(1.00,-minx); lowery = std::min<float>(1.00,-miny); rightx = max(srcim.cols-minx,maxx-minx); highery = max(srcim.rows-miny,maxy-miny);  warpperspective(srcim, dstim, h, size(rightx-leftx,highery-lowery), cv::inter_cubic); 

update: perhaps results not because matrix i'm using wrong. cannot observe what's happening inside getperspectivetransform(), cannot know how matrix computed, has small , large values, makes me think garbage. way obtain data t:

for(int row=0;row<3;row++)     for(int col=0;col<3;col++)         t.at<float>(row,col) = ((float*)(h.data + (size_t)h.step*row))[col]; 

(although output matrix getperspectivetransform() 3x3, trying access values directly via t.at<float>(row,col) leads segmentation fault.)

is right way it? perhaps why original issue arises, because not correct matrix...

if result looks wierd, it's maybe because points aren't correctly set in getperspectivetransform. vector of points need in right order (top-left, top-right, bottom-right, bottom-left).

but answer initial question, there's no such thing "optimal output size". have decide depending on want do. try , try find size fits you.

edit :

if problem comes transformation matrix, how create ? way in opencv :

vector<point2f> corners; corners.push_back(topleft); corners.push_back(topright); corners.push_back(bottomright); corners.push_back(bottomleft);   // corners of destination image // output output image, should defined before operation vector<cv::point2f> output_corner; output_corner.push_back(cv::point2f(0, 0)); output_corner.push_back(cv::point2f(output.cols, 0)); output_corner.push_back(cv::point2f(output.cols, output.rows)); output_corner.push_back(cv::point2f(0, output.rows));  // transformation matrix mat h = getperspectivetransform(corners, output_corner); 

Comments

Popular posts from this blog

matlab - Deleting rows with specific rules -

php - MySQLi multi_query results for later use -