Stretch all of the image rows in order to make them of constant length

asked 2013-10-03 05:17:20 -0500

Jorge Pereira gravatar image

updated 2013-10-03 05:22:05 -0500

Hi, I have the left side image and I want to stretch the rows in order to obtain the right side image.

image description

APPROACH 1:

This code (from here), gives me the contours.

vector< vector<Point> > contours;
contours.push_back(contour);

// you could also reuse img1 here
Mat mask = Mat::zeros(poseNormImg.rows, poseNormImg.cols, CV_8UC1);

// CV_FILLED fills the connected components found
drawContours(mask, contours, -1, Scalar(255), CV_FILLED);

// let's create a new image now
Mat crop(poseNormImg.rows, poseNormImg.cols, CV_8UC3);

// set background to green
crop.setTo(Scalar(255,255,0));

// and copy the magic apple
poseNormImg.copyTo(crop, mask);

imshow("cropped", crop);

How can I stretch the image from the contours, since it is a polygon with 10 points and and not a rectangle?

APPROACH 2:

Based on this question, I implemented this function , witch allow me to stretch a rectangle.

/**
 * http://stackoverflow.com/questions/7838487/executing-cvwarpperspective-for-a-fake-deskewing-on-a-set-of-cvpoint
 */
Mat deskewing(Mat src, Point pt1, Point pt2, Point pt3, Point pt4)
{
    vector<Point> not_a_rect_shape;
    not_a_rect_shape.push_back(pt1);
    not_a_rect_shape.push_back(pt2);
    not_a_rect_shape.push_back(pt3);
    not_a_rect_shape.push_back(pt4);

    // Assemble a rotated rectangle out of that info
    RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));
    std::cout << "Rotated box set to (" << box.boundingRect().x << "," << box.boundingRect().y << ") " << box.size.width << "x" << box.size.height << std::endl;

    Point2f pts[4];

    box.points(pts);

    cv::Point2f src_vertices[3];
    src_vertices[0] = pts[0];
    src_vertices[1] = pts[1];
    src_vertices[2] = pts[3];

    Point2f dst_vertices[4];
    dst_vertices[0] = Point(0, 0);
    dst_vertices[1] = Point(box.boundingRect().width-1, 0); // Bug was: had mistakenly switched these 2 parameters
    dst_vertices[2] = Point(0, box.boundingRect().height-1);
    dst_vertices[3] = Point(box.boundingRect().width-1, box.boundingRect().height-1);


    Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices);

    cv::Mat rotated;
    cv::Size size(src.cols/2/*box.boundingRect().width*/, box.boundingRect().height);
    warpAffine(src, rotated, warpAffineMatrix, size, INTER_LINEAR, BORDER_CONSTANT);

    return rotated;
}

Since I was not able to stretch the entire polygon sub matrix, I thought of decomposing the polygon in to rectangles, stretching those areas and then sum them.

Using this approach I have two problems: the rectangle area is re sized to min area and rotated.

Is this the correct approach or is there another way?

Thank you

edit retag flag offensive close merge delete

Comments

no one?...

Jorge Pereira gravatar imageJorge Pereira ( 2013-10-03 17:43:19 -0500 )edit