Find sub-image while ignoring transparent pixels

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
kraftydevil
Posts: 10
Joined: 2017-05-01T22:24:31-07:00
Authentication code: 1151

Find sub-image while ignoring transparent pixels

Post 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 :(
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find sub-image while ignoring transparent pixels

Post 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.
kraftydevil
Posts: 10
Joined: 2017-05-01T22:24:31-07:00
Authentication code: 1151

Re: Find sub-image while ignoring transparent pixels

Post 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?
Last edited by kraftydevil on 2019-05-19T20:29:29-07:00, edited 1 time in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find sub-image while ignoring transparent pixels

Post 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.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find sub-image while ignoring transparent pixels

Post 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.
snibgo's IM pages: im.snibgo.com
Post Reply