Simon Steinberger
Simon Steinberger

Reputation: 6815

Quantifying sharp edges in an images with Python

In order to distinguish between drawings and photos, I'd like to quantify all sharp edges in an image. Such edges are a typical feature of the drawings we're dealing with, while they occur rarely in our photos.

I heard that sharp edges result in high frequencies in a 2D FT spectrum of an image. I can produce such a spectrum with this code:

from PIL import Image
img = Image.open('test.jpg')

import numpy as np
img = img.convert('L')
img_as_np = np.asarray(img)
freq = np.fft.fft2(img_as_np)

We intend to use sample images for finding the "right" threshold for differentiating between high and low frequencies. However, the above code yields a matrix (with complex numbers) and I have no idea how to get out the actual frequencies from there. Any mathematical genius around to help me our, please :-) ?

Update: I just found the following function:

np.abs(freq)

which appears to transform the complex numbers into positive floats. Are those the frequencies I am looking for? Is this a working method for finding sharp edges in an image?

Update 2: Yes, np.abs() does the job. This question may be considered answer. But I leave it open, in case anyone knows a more reliable way of differentiating between drawings and photos.

Upvotes: 2

Views: 1861

Answers (1)

Throwback1986
Throwback1986

Reputation: 6005

If you find the 2D FFT method unsatisfactory, you might consider attacking this problem using opencv since the toolkit is highly developed and provides many tools suitable for the problem you describe.

One potential strategy: construct an image pyramid from the image in question. Then, perform an edge detection operation on the resulting set of images. Strong edges should appear at all (or most) scales in the pyramid.

Given the scenario you describe, I would expect the drawings to exhibit more high-frequency energy (i.e. edges) at the larger scales when compared to the photo pyramids. Contours may be used to visualize the edges at the various scales, if needed.

Alternatively, you might consider a wavelet solution. In particular, a Haar wavelet may be used to highlight the energy differences between your two types of images. Images with strong high frequency components will demonstrate higher values in the differencing coefficients. Thus, it's reasonable to expect that your drawings will have more signal captured in the differencing coefficients. Your discriminating process might simply compare the magnitudes of the differencing coefficients. This line of thought leads to a straightforward image classification scheme:

  1. Gather two populations of images: one group of drawings and one group of photos.
  2. Perform a 1 or 2 level discrete wavelet decomposition on each image.
  3. For each image, discard the horizontal and vertical average values, leaving the differencing components. Sum the absolute value of the differencing components to compose a descriptor for that image.
  4. Group the descriptors for each population, and perform some basic statistics. If the populations differ greatly, you might use a simply distance metric to classify an unknown image: is the image descriptor closer to drawing descriptor mean or the photo descriptor mean?
  5. If populations are not so neatly distinguished, there are lots of other classifiers that may be used, (linear discriminants, neural networks, etc.)

Upvotes: 2

Related Questions