Page 1 of 2

Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T14:49:36-07:00
by bjn
I'm letting a user zoom and rotate and position an image on a web page and then passing the parameters to a server which runs Imagemagick to produce an image.

I had a runaway server process just now, and have inspected and boiled it down to this:

convert foreground.png -distort SRT '0,0 0.0027 0 0,0' out.jpg

Where foreground is any old image (but not a plain colour canvas).

This takes full CPU and I've had an instance running for a good ten minutes now and it hasn't finished.

Of course scaling it down this far is pointless (and given what I now know I'll throw an error if they try to scale it to lower than 5% or so) but it seems to me there's an underlying bug. Maybe if you scale it far enough down so it'd be a single pixel, or something, things go wrong?

Or is there some quality flag I can set so it doesn't take a billion years for operations like this?

Thanks.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T14:53:40-07:00
by dlemstra
Can you post a link to your input image?

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T14:57:33-07:00
by bjn
It doesn't seem to matter what the input is. I see the problem for instance with this:

Code: Select all

convert http://www.austintexas.gov/sites/default/files/files/Animal_Services/cute-kitten-playing.jpg -distort SRT '0,0 0.002 0 0,0' out.jpg

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T15:35:52-07:00
by fmw42
Is this really a problem with -distort SRT or with the http download of the image?

If you get the image fully downloaded and run the command is it still that slow?

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T15:47:13-07:00
by bjn
See my original example, which didn't involve HTTP.

The problem exists whether the image is downloaded first or not.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T15:59:49-07:00
by bjn
I'm noticing with other tests that the smaller I set that scale factor the longer it takes. Even scaling an 800x600 jpeg to 0.1 is taking a good 20 seconds. I'm not sure if there's some singularity where it'll spin for ever or not, but it does seem to be much too slow regardless.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T16:02:03-07:00
by fmw42
try adding -filter point and see if that makes a difference.

It is likely the use of the default elliptical weighted averaging (EWA) for the interpolation/resampling of the pixels. This will probably take a large number of pixels around each pixel to resample and thus the slow speed. In my tests, you are basically taking a very large image and resizing the whole image to each pixel. This would be much faster using -filter point (or -filter point -interpolate bilinear) or better just using -scale.


However, the biggest issue is that you are generating the same size output as input by using -distort. Change it to +distort to get the actual output size as scaled down (which is now about 1 pixel).


convert test.jpg +distort SRT '0,0 0.002 0 0,0' result

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T16:30:09-07:00
by snibgo
This is the "infinite horizon" problem, fixed with virtual-pixel, eg:

Code: Select all

convert cute-kitten-playing.jpg -virtual-pixel Black -distort SRT 0,0,0.002,0,0,0 out.png

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T16:51:02-07:00
by fmw42
snibgo wrote:This is the "infinite horizon" problem, fixed with virtual-pixel, eg:

Code: Select all

convert cute-kitten-playing.jpg -virtual-pixel Black -distort SRT 0,0,0.002,0,0,0 out.png

Infinite horizon generally occurs with perspective or other strange distortions. I do not believe it is an issue for SRT (which is linear). The main issue I believe is that he needs to use +distort and not -distort (or he gets the image averaged for every output pixel of the same size as the input).

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T17:16:08-07:00
by snibgo
Yes, it isn't the same as perspective etc, but the effect is similar: a large number of redundant calculations, here for pixels that aren't (I suppose) needed. +distort or -virtual-pixel cures this.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T17:33:44-07:00
by bjn
+distort did not work for me, since this SRT operation is not the only thing going on. That messed up a lot of positioning for me. It may have been possible to fix all that, and I'll look into +distort in future, but right now I'm on a schedule and need to roll out this fix as soon as I can.

-scale is no good (on its own at least) because I also need the rotation and positioning, and the numbers I'm getting from my browser application fit into the SRT perfectly with no new calculations.

-filter point made things much faster but this isn't only supposed to work for this 0.2% scale edge case! It also needs to look good when the user has requested more subtle scaling. So this wasn't acceptable for quality reasons.

Setting -virtual-pixel (transparent was most appropriate in most of my cases, and white in one) did the trick. So I guess snibgo was correct -- thanks very much!

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T19:05:46-07:00
by fmw42
snibgo wrote:Yes, it isn't the same as perspective etc, but the effect is similar: a large number of redundant calculations, here for pixels that aren't (I suppose) needed. +distort or -virtual-pixel cures this.
snibgo,

You are right. Although it is not exactly the infinite horizon problem, it is related and is just that there are a lot of pixels outside the bounds of the transformation that are being wasted with unneeded calculations unless -virtual-pixel is set to a constant value rather than the default edge.

The OP really did not explain well what he was trying to achieve or the fact that there was more to his goal than just this apparently oversimplified and extreme reduction in size until just now. (In hind-sight, this is really an unfair statement and due to my not reading the original post carefully enough)

Fred

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T19:27:33-07:00
by bjn
The problem I was pointing out was very slow operation on that SRT. Though my guesses about why it was occuring were wrong, I think I specified well enough the issue I was experiencing. I did in fact point out, for example, Fred, that I was letting the user zoom, rotate and position the image, not just zoom it, and that these parameters were from the user. I thought it would be helpful to boil the command down to the one parameter which was slowing things down, and I did point out that I was doing so. I'm sorry you don't agree that it was helpful.

Regardless, you both suggested valuable things to try, and many of them paid off, some with caveats which of course would not have necessarily been clear to you given the brevity of my report. But no loss.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T19:41:31-07:00
by snibgo
We often suffer from brevity; I should have said it resembles the infinite horizon issue.

Re: Incredibly slow SRT operation when scaling to small size

Posted: 2013-09-27T20:00:02-07:00
by fmw42
Sorry, my apologies. My comment about not enough information was unfair.

It appeared to me that your usage was an incorrect attempt to scale the image to an extreme (small number of pixels), which led me to think that the -distort was filling out the image with the same resulting pixel and was not what you really wanted. I though you were really trying to do a simple scaling, down to one pixel which would need to use +distort or some other mechanism (like -scale) to avoid the excessive amount of unneeded pixel computations. So perhaps I jumped to an incorrect conclusion about what you were trying to do. I admit I did not read your original post as carefully as I should have.

In general a simple example is appropriate and helps to replicate the problem.

I must admit I focused in on the example you gave and ignored the bigger picture. Thus it never dawned on me until snibgo's comment that you had so much "out of bounds" computation that you really wanted to keep or make transparent.

Your extreme example had me confused. Now after re-reading your original post, I believe that you really do not in general have that as a working situation and you did mention that. :oops:

Again I apologize for not reading your original post as carefully as I should have and jumping to the wrong conclusion about the example and issue.