Page 1 of 1

Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T04:00:09-07:00
by Crane
Using: ImageMagick 7.0.5-3 Q16 x64 2017-03-18
On Windows 7, via the CMD prompt.

I have some manga pages I have scanned, and I want to be able to crop them as a batch.
However, at the top corner of some pages is a "read this way" marker (in case you're not used to those wacky foreigners and their right-to-left layouts).
The presence of this makes auto-cropping based on colour impossible. I can't simply crop by size, because some pages have artwork that goes right to the edge of the paper, without margins.

What I would like to do is examine a specific region of the image (the marker is always in roughly the same place), and -- if and only if that region is mostly black -- fill it with white. Or better, erase the entire horizontal field that it overlaps with.

The images are in .jpg format, if that's relevant.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T06:09:23-07:00
by Bonzo
Probably best to upload an image somewhere and link to it here as it may lead to a better answer.

You probably do not need the whole image but the marker and a reasonable area around it.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T06:21:56-07:00
by Crane
The top part of an image with the marker in question:
Image

I can't simply blindly crop the whole top margin, because some pages have art going all the way to the edge.
My hope is that if I could simply define the region which contains the mark, check whether or not it has a certain percentage of black pixels, then write over it with white, I could then just autocrop the whitespace, since that works fine for pages which don't have that mark.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T10:11:31-07:00
by fmw42
Is

Read
This
Way

always the same size and font?

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T10:14:54-07:00
by Crane
Yes, modulo the usual imprecisions of scanning.
It's also always in the same location relative to the actual panels too, though of course this doesn't mean exactly the same X/Y coordinates on each image.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T10:23:32-07:00
by fmw42
You could create a small image containing those words by cropping from one image. Then use compare to locate that template in your images. If found in a reasonable place and with a good enough metric, you can shave off to the bottom of the match area in height. See the -subimage-search option with compare.

http://www.imagemagick.org/script/compare.php
http://www.imagemagick.org/Usage/compare/

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T10:37:59-07:00
by Crane
I did try running a subimage compare, and it appeared to just hang. When I looked it up, I found that this apparently takes a very long time? I've got hundreds of pages I want to run through this, so I'd prefer something quicker...

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T10:47:33-07:00
by fmw42
If you are on Unix (Linux, Mac OSX, Windows with Cygwin or Windows 10 unix), then you can try my script normcrosscorr or rmsecorr. They are about a hundred times faster. see http://www.fmwconcepts.com/imagemagick/ ... /index.php or http://www.fmwconcepts.com/imagemagick/ ... /index.php. If you use normcrosscorr, then the test must be close to 1 rather than close to 0. But my scripts require HDRI mode for IM.

Here is a bash Unix shell script script that does what you want using compare.

Input:
Image

Template (size = 34x38):
Image

Code: Select all

theight=38
thresh=0.01
infile="R2rmWqk.jpg"
data=`compare -metric rmse -subimage-search $infile template.png null: 2>&1 | tr -cs "0-9." " "`
val=`echo "$data" | cut -d\  -f2`
yoff=`echo "$data" | cut -d\  -f4`
test=`echo "scale=6; $val < $thresh" | bc`
if [ $test -eq 1 ]; then
ht=$((yoff+theight))
convert $infile -gravity north -chop 0x$ht result.jpg
fi
Image

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T11:02:34-07:00
by snibgo
Crane wrote:However, at the top corner of some pages is a "read this way" marker ...
The search time can be reduced be searching only, say, the top 100 rows of the input image.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T11:20:58-07:00
by Crane
I can't get the -region command to work, no matter what I try. This is part of why I came here asking for advice.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T11:25:17-07:00
by fmw42
Crane wrote: 2017-03-24T11:20:58-07:00 I can't get the -region command to work, no matter what I try. This is part of why I came here asking for advice.
Why -region? Just crop the top of the image as your input.

Code: Select all

theight=38
thresh=0.01
infile="R2rmWqk.jpg"
data=`compare -metric rmse -subimage-search ${infile}[x75+0+0] template.png null: 2>&1 |\
     tr -cs "0-9." " "`
val=`echo "$data" | cut -d\  -f2`
yoff=`echo "$data" | cut -d\  -f4`
test=`echo "scale=6; $val < $thresh" | bc`
if [ $test -eq 1 ]; then
ht=$((yoff+theight))
convert $infile -gravity north -chop 0x$ht result.jpg
fi
If you want to use my rmsecorr script, then it would be (using HDRI):

Code: Select all

theight=38
thresh=0.01
data=`rmsecorr template.png  R2rmWqk.jpg null: 2>&1 | tr -cs "0-9." " "`
val=`echo "$data" | cut -d\  -f5`
yoff=`echo "$data" | cut -d\  -f2`
test=`echo "scale=6; $val < $thresh" | bc`
if [ $test -eq 1 ]; then
ht=$((yoff+theight))
convert R2rmWqk.jpg -gravity north -chop 0x$ht result2.jpg
fi

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T11:45:28-07:00
by Crane
Right, okay.
I can't even persuade ImageMagick to work at all under Cygwin.
Thank you very much for trying, but I'm done with this.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T13:10:04-07:00
by fmw42
You can recode my commands in Windows bat syntax and use just the top of the image for the compare.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T13:55:43-07:00
by Crane
I can't, I'm afraid.
I don't know enough bash command syntax to have any idea what half of the code you provided means.

Last try: can someone just provide me with a .bat file that does what I originally asked for?

I'm sorry, but I don't have enough background knowledge to employ the solutions you're giving me.
That's entirely on me, not you, but it's turning this into a waste of time for everyone involved.

Re: Erasing a region of an image only if it contains more than a certain proportion of a specified colour.

Posted: 2017-03-24T15:09:28-07:00
by fmw42
In windows, just do it manually the first time. Then you can see what is happening and build a .bat file.

# run compare on the top part of your image (70 pixel high and full width)

Code: Select all

compare -metric rmse -subimage-search R2rmWqk.jpg[x70+0+0] template.png null:
The results should look like:
58.9598 (0.00089967) @ 39,13

The first number is the rmse metric value in the range 0 to 65535 (on Q16 IM). Zero is a perfect match
The second number in parens is the metric in the range 0 to 1
The 39,13 is the location of the match.

You can see that the number in parens is 0.00089967 which is smaller than 0.01 (a 1% error, which was what I tested against for a threshold). So it is a good match at the match location

Thus the match starts at row 13. But you need to add the height of the template (38) to that to get the bottom of the match and that much needs to be chopped from the top of your image. So 13+38=51.

Then chop that off your input image:

Code: Select all

convert R2rmWqk.jpg -gravity north -chop 0x51 result.jpg
My bash script simply extract the return from compare, separates it and saves the metric in parens and the y offset for the match to variables. It then test if the metric is smaller than 0.01 and if so, then it chops the top off the image.

Sorry I do not know Windows bat scripting.