How to extract-rotate-place image?

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?".
Post Reply
allexx
Posts: 9
Joined: 2019-01-19T10:39:56-07:00
Authentication code: 1152

How to extract-rotate-place image?

Post by allexx »

Hi folks, I have what "should" be straightforward -- extract an image from a mostly-grey background, and place it in a new background, and over the past couple days everything I've tried (from snippets on the interwebz) has failed for various reasons. Help, pls!

In the interim I'm reading through https://www.imagemagick.org/Usage/masking/#bg_remove, but know I need more thorough and systematic education than reading sections piecemeal. Likewise, http://www.fmwconcepts.com/imagemagick/ ... /index.php should help, but again my education lags.

(This is a progression of https://imagemagick.org/discourse-serve ... =1&t=35370, which direction I've abandoned for it not producing good-enough results)

ImageMagic version: 7.07 32-bit on Windows 7

All input images are jpg: mostly-grey background, w/ some lighting variation, w/ a mostly-circular disc in the approximate center of the image (disc may not be perfectly circular due to camera angle, etc). The background for each image is very similar; the disc size/position are also similar, but color and contents vary.

My goal is to extract the disc from each image, rotate it by some angle, and place it into a new background w/ -gravity center

Input and output samples are below.

In each case I created the output sample, using Affinity Photo 1.6.5 (the same steps work in Photoshop 5.5, and Gimp 2.10 though selection-tool settings differ); steps are as follows:

-- open input image
-- "flood select" the grey background by using the magic-wand tool and clicking on a spot approx 1/2 the distance from the edge of the disc to the top-left corner; magic-wand settings are "tolerance (aka -fuzz) 20%, contiguous"
-- invert the selection; this selects the disc
-- "copy" (CTRL-C) the selection (i.e. disc)
-- open background image
-- paste (CTRL-V) disc into background image
-- rotate disc by X degrees
-- save output image

Sample images:

input: b1 https://pasteboard.co/HXYryuw.jpg; output b1o https://pasteboard.co/HXYrJss.jpg
input: g1 https://pasteboard.co/HXYrSyr.jpg; output g1o https://pasteboard.co/HXYrZYT.jpg
input: r1 https://pasteboard.co/HXYs7Ni.jpg; output r1o https://pasteboard.co/HXYshJ4.jpg
background: bg https://pasteboard.co/HXYspHC3.jpg

All steps performed in 1 commandline would be great, but multi-step + temp images is OK.

And while a run-able solution would be wonderful, even just guidance/references on examples I could modify/study would be much appreciated.

Many thanks!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to extract-rotate-place image?

Post by fmw42 »

This should do what you want (Windows syntax -- double the % to %% if in a .bat file)

Input:
Image


Background:
Image



# line 1 - read the g1.jpeg input
# line 2 - make a copy, set the fuzz value and the flood fill color to none (transparent)
# line 3 - do the flood fill at coordinate 50,50 which is visually about where you requested
# line 4 - extract the alpha channel to use as a mask
# line 5 - turn alpha off as needed before line 6
# line 6 - put the mask into the alpha channel of the g1.jpeg input
# line 7 - set the rotation background color to none and rotate 180 deg
# line 8 - read the background image and swap it with the previous result
# line 9 - set the gravity to center before compositing
# line 10 - composite the processed image over the background
# line 11 - write the output

Code: Select all

magick g1.jpeg ^
( -clone 0 -fuzz 20% -fill none ^
-draw "matte 50,50 floodfill" ^
-alpha extract ) ^
-alpha off ^
-compose copy_opacity -composite ^
-background none -rotate 180 ^
background.jpeg +swap ^
-gravity center ^
-compose over -composite ^
g1_rot180.jpeg
Image

If you want to see what each important step does, put +write tmpX.png before the "^" or ending ")" preceding the "^" (with a space separating them) with X = 1,2,3...

For example:

Code: Select all

magick g1.jpeg ^
( -clone 0 -fuzz 20% -fill none ^
-draw "matte 50,50 floodfill" ^
-alpha extract +write tmp1.png ) ^
-alpha off ^
-compose copy_opacity -composite +write tmp2.png ^
-background none -rotate 180 +write tmp3.png ^
background.jpeg +swap ^
-gravity center ^
-compose over -composite ^
g1_rot180.jpeg
allexx
Posts: 9
Joined: 2019-01-19T10:39:56-07:00
Authentication code: 1152

Re: How to extract-rotate-place image?

Post by allexx »

Dang!

Those who know, know!

That saved me much time (for which I'm grateful; I was in the process of dissecting "magicwand"), and self-learning (for which I'm dismayed, but still grateful he added hurriedly!)

Running that gave me this error: magick: non-conforming drawing primitive definition 'matte' @ error/draw.c/DrawImage/3331.

I replaced 'matte' w/ 'alpha', and it seems to work.

Actually, it works for green and red; for blue some part of the dis edge is eaten into. I suppose that can't be helped, and has nothing to do w/ the blue-ness -- if the disc perimeter has a pixel colored within fuzz-factor of the sampled background pixel it, and its contiguous pixels, will be made transparent.

(BTW, fmw42, I learned since my prev (first) post that you're the grand poobah behind http://www.fmwconcepts.com/imagemagick/index.php; many thanx for that resource, and for your continued input on this forum.)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to extract-rotate-place image?

Post by fmw42 »

Sorry, I wrote it in IM 6 and then swapped magick for convert. In IM 7, replace matte with alpha. Try that.


magick g1.jpeg ^
( -clone 0 -fuzz 20% -fill none ^
-draw "alpha 50,50 floodfill" ^
-alpha extract ) ^
-alpha off ^
-compose copy_opacity -composite ^
-background none -rotate 180 ^
background.jpeg +swap ^
-gravity center ^
-compose over -composite ^
g1_rot180.jpeg

You may have to adjust your fuzz value for other colors.

A more complex method might be to convert to HCL, then flood fill on the hue channel to get the mask. That may not need as large a fuzz value.
allexx
Posts: 9
Joined: 2019-01-19T10:39:56-07:00
Authentication code: 1152

Re: How to extract-rotate-place image?

Post by allexx »

Thank you -- I'll try to find info on this HCL business.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to extract-rotate-place image?

Post by fmw42 »

allexx wrote: 2019-01-24T17:14:53-07:00 Thank you -- I'll try to find info on this HCL business.

Code: Select all

convert image.suffix -colorspace HCL -channel red -separate image_hue.png
image_hue.png will be only the hue channel (single channel so grayscale). Graylevels represent hues and not colors.

But upon testing that does not separate your blue very well. It leaves a noise result when I do

Code: Select all

magick b1.jpeg -colorspace HCL -channel red -separate -fuzz 3% -fill white -opaque "gray(160)" -fill black +opaque white result.png
Post Reply