Easiest way to delete pixels with mask like PS->select_color_range; delete

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
BrianP007
Posts: 49
Joined: 2013-12-13T09:54:14-07:00
Authentication code: 6789

Easiest way to delete pixels with mask like PS->select_color_range; delete

Post by BrianP007 »

I ran new software, Perfectly Clear, on thousands of stock images and it Carpet Bombed everything near the left side of the histogram to pure, (0,0,0), black. Large chunks of shadows look as though they have been redacted with India Ink. I am trying to devise an automated method to make the nigrified (yes, it's a real word) areas transparent.

And, I don't want a quick-n-dirty hack that will cause other problems. And, I want to learn more about IM which I have used for years but have yet to master. If I actually learn something and create a cool tool, I can write-off the entire venture as Research, Education and Tools Development. Photoshopping by hand would be boring rework. Redoing the raw files from scratch would be even worse.

I have monkeyed with a most elementary task, DELETE THE BLACKISH PIXELS IN AN IMAGE, for over 2 hours. It takes about 3 clicks in Photoshop. IM has to have an easy method to do this.

Photoshop: Open, select_color_range, click on black, delete QED!
Delete obliterates all of the selected pixels. Area is vacant. See through. Just like cutting out a hole in paper with scissors.

There are a couple of simple, direct attempts which should work as documented but either do nothing at all or give incoherent error messages. AND There is is an overly complicated solution which can't possibly be the best way to achieve this simple result.

In IM, read a pic, clone, grayscale, threshold at 3% -> darks->black, white elsewhere. Makes a perfect mask.
Apply MASK method with mask image on the original image and NOTHING HAPPENS.

Code: Select all

$bim->Mask(mask=>$mim);  warn "$err" if "$err";   # Does Absolutely Nothing! 
# After MASK() and WRITE() the $BIM image is unchanged and there is No error.

Trying to composite the MASK over the image gives Error 410: composite image required

Code: Select all

$bim->Composite(compose=>'Over', mask=>$mim);  # 410!
There are not one but 2 images here: "image required"?? Huh?

The overly complicated method which ~works uses Composite and a third image:
Create a white image
Composite the target image over the white image with the mask. Seems circuitous.

Code: Select all

$nim->Composite(compose=>'Over', image=>$bim, mask=>$mim);  # Black transmutes to WHITE.
There is a DELETE, but it only works on images in an array, not on pixels.
A simple ~DELETE method would seem to be indispensable:
Method=OBLITERATE Parameters=mask=>image-handle, [Replacement_color (default is WHITE)]
Description=cut out pixels as scissors do to paper. If Alpha is present, hole becomes transparent. Color may be given to replace nuked pixels.

There HAS to be a direct way to nuke the pixels with a mask without needing a third, "assistant picture" to accomplish it.

Direct attempt using PerlMagick:

Code: Select all

	$debug = 1;	
	$MAX_DARK_PERCENT = 3;  # 3% darkest pixels
	$bfn = "P:/br2/tl-2014.0416/p1/pc/215799.pclear.q16.tif";  # Burnt
	$bim = new Image::Magick;  # Burnt Image
	$mim = new Image::Magick;  # Mask of burnt areas in Burnt Image

	# READ AN IMAGE
	$err=$bim->Read($bfn);  warn "$err" if "$err";  
	$bim->Set(alpha=>'ON');  # Turn on the Alpha channel -> RGBA. 
	$max_dark = int($bim->QuantumRange*$MAX_DARK_PERCENT/100);  # 1965

	# CLONE THE IMAGE, CONVERT TO GRAY, CONVERT VERY DARK TO BLACK AND 
	# EVERYTHING  ELSE TO WHITE TO MAKE A MASK FOR BLACKENED AREAS
	$mim = $bim->Clone();  # Copies Burnt image
	$mim->Quantize(colorspace=>'gray');  
	$mim->Write("burnt.to.gray.tif");  # Grayscale of original burnt img
	$mim->Threshold(threshold=>$max_dark);  
	$mim->Write("black.white.mask.tif");  # Grayscale of original burnt img

	# DESTROY ALL DATA IN BLACKENED AREAS OF ORIGINAL PICTURE UNDER THE BLACK
	# AREAS OF THE MASK. DELETED AREAS SHOULD BE TRANSPARENT LIKE IN PHOTOSHOP. 
	$err=$bim->Mask(mask=>$mim);  warn "$err" if "$err"; 
	$bim->Write("burnt.with.holes.tif");  # Burnt img with HOLES on BLACK.
	undef $bim, $mim;
The grayscale image is correct and the mask is absolutely BLACK (Photoshop k=0) on the dark areas, white (k=65535) elsewhere. This is confirmed by viesing the intermediate TIF files.

The "burnt.with.holes.tif" has no holes and is identical to the original. The MASK method has zero effect on the written image. The method description is rather scant: "composite image pixels as defined by the mask".
com·pos·ite verb 1. combine (two or more images) to make a single picture

Documentation:
Method=Mask; Parameters=mask=>image-handle; Description=composite image pixels as defined by the mask
NOTE: The verb "COMPOSITE" in the Mask method context has been redefined to mean "NO_NOTHING". :)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Easiest way to delete pixels with mask like PS->select_color_range; delete

Post by fmw42 »

I am trying to devise an automated method to make the nigrified (yes, it's a real word) areas transparent.
try

Code: Select all

convert image -fuzz XX% -transparent black result.png
-fuzz looks for pixels that are within the XX% of black and makes them all transparent. Do not use JPG for output, since it does not support transparency. Use PNG or TIFF

see
http://www.imagemagick.org/script/comma ... s.php#fuzz
http://www.imagemagick.org/script/comma ... ransparent
Post Reply