Page 1 of 1

Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T10:36:04-07:00
by dscully
Hello,

I'm attempting to use IM to perform a correction on an image where the green channel of a 1920x1080 RGB image is offset half a pixel in both the positive X and Y directions. My intention is to move the green channel back into alignment with the blue and red channels.

My current approach is to double the size of the image so that the correction becomes a integer number of pixels, separate each channel into a file, use page to shift the green channel with a transparent background, combine the images, and then use a point filter to scale back to the original size.

Code: Select all

convert checker.bmp -resize 200% checker2.bmp
convert -page -1-1 checker2.bmp -channel G -separate -background none -flatten checker_shifted_green.bmp
convert checker2.bmp -channel R -separate checker_red.bmp
convert checker2.bmp -channel B -separate checker_blue.bmp
convert checker_red.bmp checker_shifted_green.bmp checker_blue.bmp -set colorspace RGB -combine -set colorspace sRGB checker_combined.bmp
convert checker_combined.bmp -filter Point -resize %50 checker_combined_smaller.bmp
However, this is fairly inefficient because I do not really need the intermediate files. I was having trouble coming up with a command that does this without the need to write out the files. Also I'm interested if there is a method to avoid the resize and work directly with a floating point translation of the green channel.

Edit: I'm using version ImageMagick 7.0.2-10

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T10:49:50-07:00
by snibgo
"-distort SRT" can do sub-pixels translations. (With scale=1 and rotation=0, obviously.) So there is no need to double the size, etc.

Does that solve the problem? I don't understand your query about the "floating point translation" of the green channel.

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T11:01:53-07:00
by fmw42
You can use -distort SRT to do a fractional pixel shift (translate). See http://www.imagemagick.org/Usage/distorts/#srt

Examples:

# create tricolor image

Code: Select all

convert -size 100x100 xc:red xc:green1 xc:blue +append tricolor.png
Image

# shift by 10

Code: Select all

convert tricolor.png \
-separate +channel \
\( -clone 1 -distort SRT "10,10 1 0 0,0" \) \
-swap 1,3 +delete -combine result1.png
Image

# shift by 0.5

Code: Select all

convert tricolor.png \
-separate +channel \
\( -clone 1 -filter lanczos -distort SRT "1,1 1 0 0.5,0.5" \) \
-swap 1,3 +delete -combine result2.png
Image

# compare differences to see that it worked, since it is not visually obvious

Code: Select all

compare -metric rmse tricolor.png result2.png null:
1549.34 (0.0236413)

You may want to change the -filter to triangle for bi-linear interpolation.

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T12:50:37-07:00
by GeeMack
dscully wrote: 2017-07-13T10:36:04-07:00I'm attempting to use IM to perform a correction on an image where the green channel of a 1920x1080 RGB image is offset half a pixel in both the positive X and Y directions. My intention is to move the green channel back into alignment with the blue and red channels.
As snibgo and fmw42 have already mentioned, IM's "-distort" operator will work with fractions of pixels. The following command would separate your image into its R, G, and B channels, shift the position of the green channel 1/2 pixel to the left and 1/2 pixel up, then reassemble the three images to complete the operation.

Code: Select all

magick input.png -separate -distort affine "0,0 %[fx:t==1?-0.5:0],%[fx:t==1?-0.5:0]" -combine output.png

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T13:01:42-07:00
by fmw42
GeeMack: Nice way to do that in IM 7.

It is too bad that -distort does not allow channel modification without separating channels. This does not work.

Code: Select all

convert tricolor.png -channel green -distort SRT "10,10 1 0 0,0" +channel result.png
the result is no change.

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T13:07:57-07:00
by GeeMack
fmw42 wrote: 2017-07-13T13:01:42-07:00GeeMack: Nice way to do that in IM 7.
Since IM 6 allows the use of FX expressions in "-distort ..." operations, that method also works for me with v6.9.7 in Windows and v6.7.7 in Windows 10's bash.

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T16:50:41-07:00
by dscully
Thank you everyone, fmw42's method is fast and gets good results!

Re: Shift Individual Color Plane By Subpixel

Posted: 2017-07-13T16:56:37-07:00
by fmw42
GeeMack's method might be slightly faster and less memory intensive since he does not need to clone the green channel, swap and delete.