Jimp: Plugin: Skew

Created on 23 Sep 2018  路  8Comments  路  Source: oliver-moran/jimp

Is your feature request related to a problem? Please describe.
Per many mathematical references describing a standard x-skew, I had hoped that applying a standard matrix for this would result in a skewed image. Attempting to apply a skew transformation like this is really not resulting in anything close to what I'm attempting to achieve.

matrixskewx

I am dutifully converting an input angle like 30 into radians first before then applying a Math.tan(30 * Math.PI / 180) in this section of the matrix.

Describe the solution you'd like
I am attempting to adjust a webcam image of a forward-facing camera on a remote control car so that lanes on a straight road (in their lines-of-perspective to infinity) are now vertical in the resulting transformed image. A rectangular image should then be transformed into an isosceles trapezoid.

(Opposite of this, of course...)
screen shot 2018-09-22 at 6 28 46 pm

This first attempt is to change a rectangle into a parallelogram with an x-skew.

screen shot 2018-09-22 at 6 29 45 pm

skewexamples

Describe alternatives you've considered

function tanDeg(deg) {return Math.tan(deg * Math.PI/180);}
//var lambda =                tanDeg(config.xSkew);
var lambda =                tanDeg(90 - config.xSkew);
// exports.perspectiveSkew =   [
//                               [1, 0, 0, lambda,                      0],
//                               [0, 1, 0, 0,                           0],
//                               [0, 0, 1, 0,                           0],
//                               [0, 0, 0, 1,                           0],
//                               [0, 0, 0, 0,                           1]
//                             ];
exports.perspectiveSkew =   [
                                [1, lambda,  0],
                                [0, 1,       0],
                                [0, 0,       1]
                              ];

Additional context
Here's an example of what results from attempting to apply the x-skew matrix:

screen shot 2018-09-22 at 6 31 37 pm

plugin-candidate

Most helpful comment

In PhotoShop, the skew and perspective options are close to this. It's unlikely to find the source code for what goes on behind-the-scenes in PS, though.

The matrix:

1            tan(xSkew)   0
tan(ySkew    1            0
0            0            1

...is supposed to provide an xSkew and ySkew effect, as provided instead of the default zero that would have been there. My first link above is some documentation for that.

At this point, I'm good. My code above works for me. If you can look into skew and see if it's something you'd like to offer (and can find an approach that works for you, great. Thanks.

All 8 comments

For what it's worth, I was able to build my own prototype for the Jimp class which seems to fit my own requirements.

The config.js file in question includes xSkew as 30 in this case.

Jimp.prototype.perspective = function(cb) {
  var xSkewInRadians = Math.tan((config.xSkew * Math.PI) / 180);
  var xShear = parseInt(this.bitmap.height * xSkewInRadians);
  var xShearForThisLine = undefined;
  var original = this;

  debug('perspective xShear:' + xShear);

  new Jimp(this.bitmap.width, this.bitmap.height, '#000000FF', function(
    errNew,
    imgCanvas
  ) {
    if (errNew) {
      cb(errNew);
      return;
    }

    try {
      for (var y = 0; y < this.bitmap.height - 1; y++) {
        xShearForThisLine = parseInt((y + 1) * xSkewInRadians);
        imgCanvas.blit(
          original
            .clone()
            .crop(0, y, original.bitmap.width, 1)
            .resize(original.bitmap.width - 2 * xShearForThisLine, 1),
          xShearForThisLine,
          y
        ); // imgCanvas.blit()
      } // for
    } finally {
      cb(null, imgCanvas);
    }
  }); // new Jimp()
}; // perspective()

(I also added another prototype to chop off the top 200 pixels so don't be confused.)
screen shot 2018-09-22 at 9 34 22 pm

@OutsourcedGuru convolution isnt the thing you're looking for I think. This is what convolute does https://docs.gimp.org/2.6/en/plug-in-convmatrix.html

Can you link me to a documented function in another image manipulation program that would use your matrix? I can make a plugin that performs that.

In PhotoShop, the skew and perspective options are close to this. It's unlikely to find the source code for what goes on behind-the-scenes in PS, though.

The matrix:

1            tan(xSkew)   0
tan(ySkew    1            0
0            0            1

...is supposed to provide an xSkew and ySkew effect, as provided instead of the default zero that would have been there. My first link above is some documentation for that.

At this point, I'm good. My code above works for me. If you can look into skew and see if it's something you'd like to offer (and can find an approach that works for you, great. Thanks.

This could helpful when generating machine learning image training sets, and randomizing the input. In my case, making hundreds-thousands of variations of the input classification image, without having to do it manually. It would be slick it was built into the node jimp lib.

@OutsourcedGuru - side note - in your example:

var xShear = parseInt(this.bitmap.height * xSkewInRadians);

That line isn't used - was it suppose to be?

I was using that variable for debugging purposes since it appears in the commented-out code:

//debug('perspective xShear:' + xShear);

Hi, what would be needed to have the Skew plugin completed? Maybe with 2 x,y parameters, similar to
http://fabricjs.com/controls
(including negative values)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PainKKKiller picture PainKKKiller  路  5Comments

sesirimarco picture sesirimarco  路  3Comments

slidenerd picture slidenerd  路  4Comments

DylanPiercey picture DylanPiercey  路  4Comments

Favna picture Favna  路  4Comments