0

I want to upscale / stretch an image horizontally but each pixel row needs a different scale depending upon the position of the row or row-number ?

I did it by cropping source image row by row int a 1 pixel high crop and then using resize to do scale each row differently as I want, and finally copy the scaled row of pixels on a resultant image: here's my code:

        cv::Rect rowCropRect = cv::Rect(0,i, imgOut.size().width, 1);
        cv::Size scaledSize = cv::Size((1.f - smallFrameRatio) * rowCropRect.size().width, 1);

        if (smallestWidth < scaledSize.width)
            smallestWidth = scaledSize.width;

        Mat eachRowCrop(imgIn, rowCropRect);
        resize(eachRowCrop, eachRowCrop, scaledSize);

        rowCropRect.x = (imgIn.size().width - eachRowCrop.size().width) * 0.5f;
        rowCropRect.width = eachRowCrop.size().width;

        if (rowCropRect.x < 0) rowCropRect.x = 0;
        if (rowCropRect.width >= imgOut.size().width) rowCropRect.width = imgOut.size().width - 5;

        eachRowCrop.copyTo(imgOut(rowCropRect));
        eachRowCrop.release();

I'm doing this by iterating each row in a loop. But its slower and resultant transform is not good enough.

I want to be able to do it directly at pixel level, using some interpolation maths which cv::resize() is internally using, OR some other efficient way.

Any ideas ?

SourceImage:

enter image description here

ResultImage:

enter image description here

Sabir Ali
  • 475
  • 2
  • 16
  • check out [warpPerspective](http://docs.opencv.org/2.4.0/modules/imgproc/doc/geometric_transformations.html#warpperspective) – slawekwin Oct 05 '16 at 11:39
  • Thank you, I've seen it but don't know how can I prepare the 3x3 transformation matrix ? because in my case I just know the amount of scale I need to apply on each row, which is different for all rows of the image. ? any ideas on preparing such a transform and how to tell it what scale to apply at what row number ? – Sabir Ali Oct 05 '16 at 11:44
  • you can get it with [getPerspectiveTransform](http://docs.opencv.org/2.4.0/modules/imgproc/doc/geometric_transformations.html?Mat%20getPerspectiveTransform(const%20Point2f*%20src,%20const%20Point2f*%20dst)#getperspectivetransform) by providing desired result sized quadrangle to `dst` argument – slawekwin Oct 05 '16 at 11:49
  • actually there are more than 4 fixed points. I've added a required result image above. Please review. Please note that this is not the exact same transform which I want, it can be of any shape. The rule is that any row would have different scale which I know the value of. Thanks. – Sabir Ali Oct 05 '16 at 12:28
  • @slawekwin - can you please explain a little on how can I use your suggested APIs in my solution above ? I'm not much comfortable at openCV, so any help would be much appreciated. – Sabir Ali Oct 06 '16 at 16:11
  • I thought your transformation was more... regular. If you wish to achieve an arbitrary scaling for individual lines this probably won't help you. – slawekwin Oct 07 '16 at 06:11
  • @slawekwin - Right. I know I have to do the interpolation myself, something which cv::resize() function does internally on each pixel, but instead of constant scale I need to apply different scale on each row. Can you suggest me something on these lines please ? – Sabir Ali Oct 07 '16 at 07:09

1 Answers1

1

Try using the remap function, as is outlined in this tutorial. It should allow you to set a new x- and y- location for each point in your image (and it handles all the interpolation).

Paul Wintz
  • 2,542
  • 1
  • 19
  • 33