Page 1 of 1

Find sub-image while ignoring transparent pixels

Posted: 2019-05-19T15:03:46-07:00
by kraftydevil
I'd like to take an image containing transparent pixels and search for its opaque pixels inside another image, obtaining its location.

Example

Image 1, containing transparent pixels:
Image

Image 2:
Image

Concept

The transparent pixels in Image 1 should be ignored when matching inside Image 2. The idea is that no matter what Image 2's background contains, I am only trying to match the opaque parts of Image 1 in Image 2.

Is this a special case, or does the subimage-search cover this? I'm guessing I'd have to adjust the matching threshold but there's so many options I don't know where to start.

Goal

Ultimately, I'm trying to find a cursor in a video stream that looks like this (2880x1600):
Image

This cursor is part transparent, so anything could be behind it :(

Re: Find sub-image while ignoring transparent pixels

Posted: 2019-05-19T15:49:06-07:00
by fmw42
You can do that in Imagemagick 7 only. It is done using a mask image. You need to extract he mask from the alpha channel. See viewtopic.php?f=4&t=31053

For you cursor, your smaller image and the mask image must be the same size as the cursor you are trying to located. The compare function does not work if there are scale or rotation. It is a purely translation operation.

Re: Find sub-image while ignoring transparent pixels

Posted: 2019-05-19T20:26:13-07:00
by kraftydevil
fmw42 wrote: 2019-05-19T15:49:06-07:00 You can do that in Imagemagick 7 only. It is done using a mask image. You need to extract he mask from the alpha channel. See viewtopic.php?f=4&t=31053

For you cursor, your smaller image and the mask image must be the same size as the cursor you are trying to located. The compare function does not work if there are scale or rotation. It is a purely translation operation.
Good news! It worked!

I cleaned up some of the image names in case anyone is wondering what images to plug in where:

Code: Select all

magick compare -metric rmse -subimage-search -dissimilarity-threshold 1 image-to-search-in.png \( -read-mask mask-of-image-to-search-for.png image-to-search-for.png \) result-has-no-use.png
Bad news #1: My rmagick install doesn't work anymore because it only works with IM 6. Is there a way to use 2 different versions? I'm on a mac.
Bad news #2: It's super slow - takes about 3 minutes. How can I get this done to less than 2 seconds?

Re: Find sub-image while ignoring transparent pixels

Posted: 2019-05-19T22:39:48-07:00
by fmw42
You can resize your images smaller, do the comparison, find the location, then crop near that area, then compare on the subsection to refine the location.

I run my Mac with IM 7 installed. But I can compile, but not install IM 7. The I use a script to call the IM 7 version. You may contact me via PM on the forum and send me your personal email, if you want me to send you the script. I do not use Rmagick. So I cannot help with that.

Re: Find sub-image while ignoring transparent pixels

Posted: 2019-05-19T22:56:39-07:00
by snibgo
wrote:It's super slow - takes about 3 minutes. How can I get this done to less than 2 seconds?
As Fred says, a multi-scale search is faster.

If you build IM yourself, you can use my Process modules, such as srchimg. When the subimage ("image-to-search-for") is large, this is massively faster than IM's built-in search, eg a factor of 100. An alternative module aggrsrch is for cases where the subimage is small (eg search for a cursor within a screenshot).

If you link to sample images, I can test the speeds so you can decide if they are worthwhile. But if you can't rebuild IM, you won't be able to use the modules.

Alternatively, a script can be used for multi-scale or aggressive searching.