rearrange vertical pixel row

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

Perhaps I do not understand the issue. All I can say is that when I tested the change to your desired behavior, it messed up the look of the results of my scripts. But after Magick made it interpolate sensitive, my scripts were producing the proper results.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: rearrange vertical pixel row

Post by anthony »

Which is why I am now suggestion that -spread does it using interpolate/virtual-pixel, while +spread does it by pixel swapping.
That way you remain backward compatible with the old behaviour. While providing a method to preserve the exact pixel colors of the original image without loss and duplication (just shuffling the pixels like cards, but only to nearby locations).

What script was effected?

The point is the current spread losses image information, a LOT of information. Which is NOT what the documentation for the command says it should be doing. The addition of the new version will make existing scripts (and API) work as before, but with without data loss.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

OK. Thanks for the explanation.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rearrange vertical pixel row

Post by snibgo »

Hmmm because of the bias, perhaps the pixel preservation should use a '+' form. While we use the original as 'normal' mode, and adjust the documentation to reflect the actual nature of spread. IE: interpolated spread by default.

What are the thoughts of you Fred? Snibgo?
I think radically changing the behaviour of "-spread" is a bad idea. People who use it currently will find that it no longer works.

If we want a new operator that does something different, eg swapping pixels without creating new colours, call it "+spread" or "-swappixels" or whatever.

I would expect a "swap-pixel" operation to be symmetrical, both horizontally and vertically. At each iteration, the values of two pixels are swapped. The swapped values are from all channels, or just those in a "-channel" setting. Each pixel would be swapped exactly once (possibly with itself).

I don't think this can be done without an extra temporary channel, binary, to record whether each pixel has already been swapped. IM v6 doesn't have a mechanism for extra temporary channels, so this requires a temporary image of the same size.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: rearrange vertical pixel row

Post by anthony »

snibgo wrote:
Hmmm because of the bias, perhaps the pixel preservation should use a '+' form. While we use the original as 'normal' mode, and adjust the documentation to reflect the actual nature of spread. IE: interpolated spread by default.

What are the thoughts of you Fred? Snibgo?
I think radically changing the behaviour of "-spread" is a bad idea. People who use it currently will find that it no longer works.

If we want a new operator that does something different, eg swapping pixels without creating new colours, call it "+spread" or "-swappixels" or whatever.
Which is why I backed off from my former stance of - it does not follow the dociumentation.

The solution is add the new functionality as a new feature (EG: +spread) or operator (I'd prefer feature as it is closely related)
and then fix the documentation.

The Usage notes I created is now online http://www.imagemagick.org/Usage/transform/#spread
I will modify this when Cristy makes the suggested change. I thought about DIY'ing this myself, I don't want to get sucked back into that level of development again! I have too many other things in my life.
I would expect a "swap-pixel" operation to be symmetrical, both horizontally and vertically. At each iteration, the values of two pixels are swapped. The swapped values are from all channels, or just those in a "-channel" setting. Each pixel would be swapped exactly once (possibly with itself).
Which is what I though spread was doing from the documentation. Obviously not the case. This could be quite tricky to achieve! Especially without a directional bias, as by progressing through the image you are giving some type of directionality to the processing.
I don't think this can be done without an extra temporary channel, binary, to record whether each pixel has already been swapped. IM v6 doesn't have a mechanism for extra temporary channels, so this requires a temporary image of the same size.
That was my thoughts, IMv7 can have extra channels... A IM v6 version however can create a extra image to do that tracking (expensive though that is, especially for binary flags) Though if you are not using CMYK you could temporarily create a black channel to hold that flag data.

Note that one speed up would be is to only swap the current pixel with a random pixels ahead of the processing, as all the pixels behind that processing has already been swapped. That reduced the pixel to select by half. But that would only worsen the directional bias caused by double swapping.

Correctly spreading pixels using a local neighbourhood is turning out to be a real problem!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rearrange vertical pixel row

Post by snibgo »

The process is greatly simplified if no local neighbourhood is defined, so the swapping is between any two pixels in the image. Then, there is no bias (I think) so no need to keep track of which pixels have swapped. Users could "cap" the extent of swapping by cropping a portion of the image, swapping that, and compositing the result in the same location over the original.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: rearrange vertical pixel row

Post by anthony »

I don't think splitting up the image and swapping in sections is a great way to do it.

Hmmm... I think we will need to look for a 'limited shuffle' algorithm to use before we can get a proper, no bias, pixel spread function.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: rearrange vertical pixel row

Post by anthony »

out of curiousity I took a look at source of ppmspread from the netpbm package (version 10.66.2) with which I assume the IM version had a common ancestor.

First it only deals with whole pixels, no interpolation or virtual pixels. Which were never normal features of the NetPBM package.

Psuedo Code....

Code: Select all

For each pixel P, selects a random location nearby N
If N is outside image proper (a virtual pixel location) It just copies src P to dest P
Otherwise... and this is a ltlle strange.
    it copies src P  into dest N
    then copies src N into dest P
Now as it only reads from the source image, you cannot get a double swap.
now if N is behind the current P's location the two pixels effectively get swapped,
but at the code of destorying whatever value was already saved into N
But if N is ahead of the current P's location the pixel in N will always be replaced with a new pixel.

This seems different to just the simple single 'random pick' from destination ImageMagick's origina spread function is doing, but it still losses information.

The PPM source code also says it is 'pixel swapping' though obviously that is not actually the case.

For example.. I create a 3x3 pixel image, with unique numbers 1 to 9, the use ppmspread 1

Confirmation....

Code: Select all

echo P2 3 3 9 1 2 3 4 5 6 7 8 9 | ppmspread 1 | ppmtopgm | pnmdepth 9 | pnmtopnm -plain
P2
3 3
9
2 6 3
4 2 2
8 9 8
As you can see in this run we lost pixel's 1, 5, and 7. replace by two duplicates of pixel 2 and one of pixel 8

However IM using the new method (even with the directional bias cause by double-swapping) does indeed preserve
the pixel data without loss/duplication.

Code: Select all

echo P2 3 3 9 1 2 3 4 5 6 7 8 9 | magick - -spread 1 pgm:- | pnmdepth 9 | pnmtopnm -plain
P2
3 3
9
3 6 4
7 1 5
2 9 8
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply