简体   繁体   中英

Command-line tools to match similar portions of an image

I've got a few thousand scanned images that I am trying to crop. I'm writing a script that will crop the pictures accordingly if I can determine whether the source image is a 3x5 picture or a 4x6 picture from the uncropped border (scanner lid).

I've found command-line tools to compare and match entire images (using imagemagick convert), but not a designated region of an image:

convert img1.jpg  "img2.jpg" -compose difference -composite -colorspace gray miff:- | identify -verbose - | sed -n '/^.*mean: */{s//scale=2;/;s/(.*)//;s/$/*100\/32768/;p;q;}' | bc

(it's usually a match if the result < .10, but it is cpu-intensive)

Is there a tool or Python image library that will let me match compare certain regions from two images to see if they match? The uncropped regions are not plain white, as evidenced by the example images below (1 3x5, 1 4x6). All I need to match is the first 100 or so pixels, and obviously I can't match the entire image. I have considered copying and cropping the image and matching the crop to a reference image, but that seems less than optimal.

在此输入图像描述

在此输入图像描述

I am unaware of the existence of a specific command-line tool to do this, but it would be pretty trivial to write your own using numpy . The basic procedure would be:

  1. Have the plain image of the scanner's lid load into a ndarray .
  2. Load each photo/image in a ndarray.
  3. Compare the significant portion of the two and assign a score.
  4. If the score is above your threshold...

If performance is an issue, step #2 could be optimised by moving along the file with seek() and only reading portions of it to speed things up.

A proof-of-concept implementation of the numpy part:

>>> import numpy as np
>>> scanner_lid = np.ones((5, 5))
>>> scanner_lid
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
>>> photo = np.random.randint(0, 2, (5, 5))
>>> photo
array([[0, 0, 1, 1, 0],
       [0, 1, 1, 1, 0],
       [0, 0, 1, 1, 1],
       [1, 1, 0, 0, 1],
       [1, 0, 1, 1, 1]])
>>> matching_pixels = scanner_lid[0:2, 0:2] == photo[0:2, 0:2]  #compare the top-left 4 pixels
>>> matching_pixels
array([[False, False],
       [False,  True]], dtype=bool)
>>> np.sum(matching_pixels)
1

Of course in a real-world application you should probably measure the difference between the pixel values as intensity and colour balance might change from scan to scan, etc... Yet, I think it wouldn't require a lot of time to come up with something usable for your job.

HTH!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM