Pregunta

my question is about the world of images in iOs. My goal is to calculate or obtain in some way the "in focus" area of an image. I would like to know in which part of the image there is the focus. Do you know if there is a way to do that? Maybe working with contrast? I search a lot but I didn't find anything.

¿Fue útil?

Solución

You have to divide your image into suitable regions and calculate the gradient image for each region. A sharp region will have a high gradient value(s) and a blurred will have a low.

I include an example in Python but I am sure you can convert it to a language of your choice. I have applied the gradient calculations to an entire image but you would just replace the image im with your window.

Below is a montage that shows the blurring effect over the iterations and the average gradient value at each iteration. The maximum gradient value can be found at the first image and that is also the sharpest image (i.e. in focus) in this example. enter image description here

enter image description here

import cv2
import matplotlib.pylab as pl

# Load the image
original_image = cv2.imread('lena.jpg')

# Generate the smoothing kernel
kernel = cv2.getGaussianKernel(9,1)

# I played around with this value and found that there was not
# much change after 10 iteration
num_of_iter = 9

# Define containers
average_gradient = []
blurred_imlist = []

blurred_imlist.append(original_image)


# Blur the image iteratively and use the output from the previous iteration as
# input to the next
for i in range(0,num_of_iter):
    # Get the blurred image from the previous step
    im = blurred_imlist[i]

    # Calculate the gradient
    sobelx = cv2.Sobel(im,cv2.CV_64F,1,0,ksize=5)
    sobely = cv2.Sobel(im,cv2.CV_64F,0,1,ksize=5)

    abs_sobel_x = cv2.convertScaleAbs(sobelx) # converting back to uint8
    abs_sobel_y = cv2.convertScaleAbs(sobely)

    # Combine the two gradients with equal weight
    dst = cv2.addWeighted(abs_sobel_x,0.5,abs_sobel_y,0.5,0)

    # Calculate the average gradient for the image
    # I convert it to a numpy array for ease of calculation
    average_gradient.append(pl.asarray(dst).mean())



    # Blur it and this as input to the next iteration
    blurred_im = cv2.filter2D(im, -1, kernel)
    blurred_imlist.append(blurred_im)


# The index with the maximum gradient value is your in-focus image
infocus_image = pl.argmax(pl.asarray(average_gradient))
print(infocus_image)    

0

Otros consejos

An out-of-focus image of a sharp subject is identical to an in-focus image of a blurry subject, so there is no algorithm can do this in the general case.

If you assume that your in-focus area has a certain amount of micro-contrast, then you can simply find all pixels that differ from their neighbors by more than a set threshold. (Compute the pixel value minus the mean of the four neighboring pixels. This is the called the divergence of the gradient or the Laplacian.) Some video-recording systems do this to help the operator find focus.

If you have a sequence of images with varying focus, then you can compute the above for each image to find out which one has the best focus. This is how the AF-system in many compact cameras works.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top