Количественная четкость с использованием частот [дубликат]

Решения здесь:

  1. Используйте None в качестве значения по умолчанию (или nonce object) и включите его, чтобы создать свои значения во время выполнения; или
  2. Используйте параметр lambda в качестве параметра по умолчанию и вызовите его в блоке try, чтобы получить значение по умолчанию (это то, что требуется для лямбда-абстракции).

Второй вариант хорош, потому что пользователи функции могут проходить в вызываемом, который может уже существовать (например, type)

166
задан Sam 14 October 2011 в 10:41
поделиться

12 ответов

да, это так. вычислить fft и проанализировать результат. Преобразование Фурье сообщает вам, какие частоты присутствуют в изображении. Если есть небольшое количество высоких частот, тогда изображение размыто.

Определение терминов «низкий» и «высокий» зависит от вас.

изменить: как указано в комментарии, если вы хотите, чтобы один поплавок, представляющий размытость данного изображения, вам нужно разработать подходящую метрику.

Ответ nikie дает такую ​​метрику. Сконвертируйте изображение с ядром Лапласа:

   1
1 -4  1
   1

И используйте на выходе надежную максимальную метрику, чтобы получить число, которое вы можете использовать для порогового значения. Старайтесь избегать сглаживания изображений, прежде чем вычислять лапласиан, потому что вы обнаружите, что сглаженное изображение действительно размыто: -).

106
ответ дан Community 21 August 2018 в 05:55
поделиться
  • 1
    только проблема «низкий» и «высокий» также зависит от сцены. +1 – kenny 14 October 2011 в 11:45
  • 2
    Если ваше изображение не циклично, вы, как правило, будете иметь острые края на границах изображения, которые приводят к очень высоким частотам – Niki 14 October 2011 в 12:04
  • 3
    вы обычно практически расширяете свое изображение, чтобы избежать этого эффекта. вы также можете использовать небольшие окна для вычисления локального fft. – Simon 14 October 2011 в 12:42
  • 4
    Только один момент, который чрезвычайно важен, заключается в том, что вам нужно знать (по крайней мере, грубо), каков ваш ожидаемый pre-blurred контент (частота). Это верно, так как частотный спектр будет таким же, как у исходного изображения, чем у фильтра размытия. Таким образом, если исходное изображение уже имело преимущественно низкие частоты, как вы можете определить, было ли оно размыто? – Chris A. 14 October 2011 в 15:16
  • 5
    Если вы берете фотографию пустой белой диаграммы, вы не можете сказать, размыто ли изображение или нет. Я думаю, что OP хочет провести абсолютную резкость. возможно, ранее не было изображения. Вы должны немного поработать с правильной метрикой, но fft может помочь с этой проблемой. В этой перспективе ответ Ники лучше, чем мой. – Simon 14 October 2011 в 15:34

i реализовал его, используя fft в matlab и проверив гистограмму среднего значения вычисления fft и std, но также можно выполнить функцию

fa =  abs(fftshift(fft(sharp_img)));
fb = abs(fftshift(fft(blured_img)));

f1=20*log10(0.001+fa);
f2=20*log10(0.001+fb);

figure,imagesc(f1);title('org')
figure,imagesc(f2);title('blur')

figure,hist(f1(:),100);title('org')
figure,hist(f2(:),100);title('blur')

mf1=mean(f1(:));
mf2=mean(f2(:));

mfd1=median(f1(:));
mfd2=median(f2(:));

sf1=std(f1(:));
sf2=std(f2(:));
1
ответ дан CRABOLO 21 August 2018 в 05:55
поделиться

Ответы выше объясняли многие вещи, но я думаю, что полезно сделать концептуальное различие.

Что делать, если вы снимаете совершенно нефокусированную картину размытого изображения?

Проблема обнаружения размытия является хорошей, если у вас есть ссылка . Если вам нужно разработать, например, систему автофокусировки, вы сравниваете последовательность изображений, сделанных с разной степенью размытия или сглаживания, и вы пытаетесь найти точку минимального размытия в этом наборе. Другими словами, вам нужно перекрестно ссылаться на различные изображения, используя один из описанных выше методов (в основном - с различными возможными уровнями уточнения подхода - поиск одного изображения с самым высоким высокочастотным контентом).

3
ответ дан Emerald Weapon 21 August 2018 в 05:55
поделиться
  • 1
    Другими словами, это относительное понятие, можно только сказать, является ли изображение более или менее размытым, чем другое подобное изображение. то есть, если он имеет более или менее высокочастотное содержание в своем БПФ. Частный случай: что, если изображение имеет соседние пиксели с максимальной и минимальной яркостью? Например, полностью черный пиксель рядом с полностью белым пикселом. В этом случае это идеальный фокус, иначе будет более плавный переход от черного к белому. Идеальный фокус не вероятен при съемке, но вопрос не указывает источник изображения (он может быть сгенерирован компьютером). – Ben 13 January 2016 в 23:53

Я попробовал решение на основе лапласианского фильтра из этого сообщения. Это мне не помогло. Итак, я попробовал решение из этого сообщения , и это было хорошо для моего случая (но медленного):

import cv2

image = cv2.imread("test.jpeg")
height, width = image.shape[:2]
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

def px(x, y):
    return int(gray[y, x])

sum = 0
for x in range(width-1):
    for y in range(height):
        sum += abs(px(x, y) - px(x+1, y))

Меньше размытого изображения имеет максимальное значение sum!

Вы также можете настроить скорость и точность, изменив шаг, например

эту часть

for x in range(width - 1):

вы можете заменить на это

for x in range(0, width - 1, 10):
2
ответ дан Exterminator13 21 August 2018 в 05:55
поделиться

Спасибо, что за это великое предложение Лапласа. OpenCV docs указал мне в том же направлении: используя python, cv2 (opencv 2.4.10) и numpy ...

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) numpy.max(cv2.convertScaleAbs(cv2.Laplacian(gray_image,3)))

составляет от 0 до 255. Я обнаружил, что что-то более 200ish очень сосредоточено, и на 100 человек заметно размыто. max никогда не получает намного меньше 20, даже если он полностью размыт.

13
ответ дан ggez44 21 August 2018 в 05:55
поделиться
  • 1
    Я получил 255 для 3 моих фотографий. И для одной идеально сфокусированной фотографии мне досталось 108. Итак, я думаю, что эффективность метода зависит от чего-то. – WindRider 2 June 2018 в 15:26
  • 2
    Согласовано с @WindWider. Образец изображения, где это не удается, - это это изображение . Я думаю, причина в том, что, хотя изображение неустойчиво, контраст изображения и соответствующие различия в интенсивности между пикселями являются большими, из-за чего значения Лапласа относительно велики. Пожалуйста, поправьте меня, если я ошибаюсь. – Resham Wadhwa 28 June 2018 в 08:59
  • 3

Я придумал совершенно другое решение. Мне нужно было проанализировать видео неподвижные кадры, чтобы найти самый острый в каждом (X) кадре. Таким образом, я обнаружил бы размытие движения и / или изображение с фокусом.

Я закончил использовать обнаружение Canny Edge, и я получил ОЧЕНЬ ОЧЕНЬ хорошие результаты почти с каждым видом видео (с использованием метода nikie, я проблемы с цифровыми видео VHS и тяжелыми чересстрочными видеороликами).

Я оптимизировал производительность, установив интересующую область (ROI) на исходное изображение.

Использование EmguCV:

//Convert image using Canny
using (Image<Gray, byte> imgCanny = imgOrig.Canny(225, 175))
{
    //Count the number of pixel representing an edge
    int nCountCanny = imgCanny.CountNonzero()[0];

    //Compute a sharpness grade:
    //< 1.5 = blurred, in movement
    //de 1.5 à 6 = acceptable
    //> 6 =stable, sharp
    double dSharpness = (nCountCanny * 1000.0 / (imgCanny.Cols * imgCanny.Rows));
}
17
ответ дан Goldorak84 21 August 2018 в 05:55
поделиться

Код Matlab двух методов, опубликованных в высоко оцененных журналах (IEEE Transactions on Image Processing), доступен здесь: https://ivulab.asu.edu/software

проверить алгоритмы CPBDM и JNBM. Если вы проверите код, его не очень сложно портировать, и, кстати, он основан на методе Марциалиано как основной функции.

1
ответ дан Marco 21 August 2018 в 05:55
поделиться

Во время некоторой работы с объективом с автоматической фокусировкой я наткнулся на этот очень полезный набор алгоритмов для обнаружения фокуса изображения . Он реализован в MATLAB, но большинство функций довольно легко переносить в OpenCV с помощью filter2D .

Это в основном обзорная реализация многих алгоритмов измерения фокусировки. Если вы хотите прочитать оригинальные статьи, в коде содержатся ссылки на авторов алгоритмов. В статье 2012 г. Пертуз и др. Анализ операторов фокусировки для формы из фокуса (SFF) дает отличный обзор всех этих показателей, а также их производительности (как с точки зрения скорости, так и точности применительно к SFF).

EDIT: Добавлен код MATLAB на всякий случай, когда ссылка замирает.

function FM = fmeasure(Image, Measure, ROI)
%This function measures the relative degree of focus of 
%an image. It may be invoked as:
%
%   FM = fmeasure(Image, Method, ROI)
%
%Where 
%   Image,  is a grayscale image and FM is the computed
%           focus value.
%   Method, is the focus measure algorithm as a string.
%           see 'operators.txt' for a list of focus 
%           measure methods. 
%   ROI,    Image ROI as a rectangle [xo yo width heigth].
%           if an empty argument is passed, the whole
%           image is processed.
%
%  Said Pertuz
%  Abr/2010


if ~isempty(ROI)
    Image = imcrop(Image, ROI);
end

WSize = 15; % Size of local window (only some operators)

switch upper(Measure)
    case 'ACMO' % Absolute Central Moment (Shirvaikar2004)
        if ~isinteger(Image), Image = im2uint8(Image);
        end
        FM = AcMomentum(Image);

    case 'BREN' % Brenner's (Santos97)
        [M N] = size(Image);
        DH = Image;
        DV = Image;
        DH(1:M-2,:) = diff(Image,2,1);
        DV(:,1:N-2) = diff(Image,2,2);
        FM = max(DH, DV);        
        FM = FM.^2;
        FM = mean2(FM);

    case 'CONT' % Image contrast (Nanda2001)
        ImContrast = inline('sum(abs(x(:)-x(5)))');
        FM = nlfilter(Image, [3 3], ImContrast);
        FM = mean2(FM);

    case 'CURV' % Image Curvature (Helmli2001)
        if ~isinteger(Image), Image = im2uint8(Image);
        end
        M1 = [-1 0 1;-1 0 1;-1 0 1];
        M2 = [1 0 1;1 0 1;1 0 1];
        P0 = imfilter(Image, M1, 'replicate', 'conv')/6;
        P1 = imfilter(Image, M1', 'replicate', 'conv')/6;
        P2 = 3*imfilter(Image, M2, 'replicate', 'conv')/10 ...
            -imfilter(Image, M2', 'replicate', 'conv')/5;
        P3 = -imfilter(Image, M2, 'replicate', 'conv')/5 ...
            +3*imfilter(Image, M2, 'replicate', 'conv')/10;
        FM = abs(P0) + abs(P1) + abs(P2) + abs(P3);
        FM = mean2(FM);

    case 'DCTE' % DCT energy ratio (Shen2006)
        FM = nlfilter(Image, [8 8], @DctRatio);
        FM = mean2(FM);

    case 'DCTR' % DCT reduced energy ratio (Lee2009)
        FM = nlfilter(Image, [8 8], @ReRatio);
        FM = mean2(FM);

    case 'GDER' % Gaussian derivative (Geusebroek2000)        
        N = floor(WSize/2);
        sig = N/2.5;
        [x,y] = meshgrid(-N:N, -N:N);
        G = exp(-(x.^2+y.^2)/(2*sig^2))/(2*pi*sig);
        Gx = -x.*G/(sig^2);Gx = Gx/sum(Gx(:));
        Gy = -y.*G/(sig^2);Gy = Gy/sum(Gy(:));
        Rx = imfilter(double(Image), Gx, 'conv', 'replicate');
        Ry = imfilter(double(Image), Gy, 'conv', 'replicate');
        FM = Rx.^2+Ry.^2;
        FM = mean2(FM);

    case 'GLVA' % Graylevel variance (Krotkov86)
        FM = std2(Image);

    case 'GLLV' %Graylevel local variance (Pech2000)        
        LVar = stdfilt(Image, ones(WSize,WSize)).^2;
        FM = std2(LVar)^2;

    case 'GLVN' % Normalized GLV (Santos97)
        FM = std2(Image)^2/mean2(Image);

    case 'GRAE' % Energy of gradient (Subbarao92a)
        Ix = Image;
        Iy = Image;
        Iy(1:end-1,:) = diff(Image, 1, 1);
        Ix(:,1:end-1) = diff(Image, 1, 2);
        FM = Ix.^2 + Iy.^2;
        FM = mean2(FM);

    case 'GRAT' % Thresholded gradient (Snatos97)
        Th = 0; %Threshold
        Ix = Image;
        Iy = Image;
        Iy(1:end-1,:) = diff(Image, 1, 1);
        Ix(:,1:end-1) = diff(Image, 1, 2);
        FM = max(abs(Ix), abs(Iy));
        FM(FM<Th)=0;
        FM = sum(FM(:))/sum(sum(FM~=0));

    case 'GRAS' % Squared gradient (Eskicioglu95)
        Ix = diff(Image, 1, 2);
        FM = Ix.^2;
        FM = mean2(FM);

    case 'HELM' %Helmli's mean method (Helmli2001)        
        MEANF = fspecial('average',[WSize WSize]);
        U = imfilter(Image, MEANF, 'replicate');
        R1 = U./Image;
        R1(Image==0)=1;
        index = (U>Image);
        FM = 1./R1;
        FM(index) = R1(index);
        FM = mean2(FM);

    case 'HISE' % Histogram entropy (Krotkov86)
        FM = entropy(Image);

    case 'HISR' % Histogram range (Firestone91)
        FM = max(Image(:))-min(Image(:));


    case 'LAPE' % Energy of laplacian (Subbarao92a)
        LAP = fspecial('laplacian');
        FM = imfilter(Image, LAP, 'replicate', 'conv');
        FM = mean2(FM.^2);

    case 'LAPM' % Modified Laplacian (Nayar89)
        M = [-1 2 -1];        
        Lx = imfilter(Image, M, 'replicate', 'conv');
        Ly = imfilter(Image, M', 'replicate', 'conv');
        FM = abs(Lx) + abs(Ly);
        FM = mean2(FM);

    case 'LAPV' % Variance of laplacian (Pech2000)
        LAP = fspecial('laplacian');
        ILAP = imfilter(Image, LAP, 'replicate', 'conv');
        FM = std2(ILAP)^2;

    case 'LAPD' % Diagonal laplacian (Thelen2009)
        M1 = [-1 2 -1];
        M2 = [0 0 -1;0 2 0;-1 0 0]/sqrt(2);
        M3 = [-1 0 0;0 2 0;0 0 -1]/sqrt(2);
        F1 = imfilter(Image, M1, 'replicate', 'conv');
        F2 = imfilter(Image, M2, 'replicate', 'conv');
        F3 = imfilter(Image, M3, 'replicate', 'conv');
        F4 = imfilter(Image, M1', 'replicate', 'conv');
        FM = abs(F1) + abs(F2) + abs(F3) + abs(F4);
        FM = mean2(FM);

    case 'SFIL' %Steerable filters (Minhas2009)
        % Angles = [0 45 90 135 180 225 270 315];
        N = floor(WSize/2);
        sig = N/2.5;
        [x,y] = meshgrid(-N:N, -N:N);
        G = exp(-(x.^2+y.^2)/(2*sig^2))/(2*pi*sig);
        Gx = -x.*G/(sig^2);Gx = Gx/sum(Gx(:));
        Gy = -y.*G/(sig^2);Gy = Gy/sum(Gy(:));
        R(:,:,1) = imfilter(double(Image), Gx, 'conv', 'replicate');
        R(:,:,2) = imfilter(double(Image), Gy, 'conv', 'replicate');
        R(:,:,3) = cosd(45)*R(:,:,1)+sind(45)*R(:,:,2);
        R(:,:,4) = cosd(135)*R(:,:,1)+sind(135)*R(:,:,2);
        R(:,:,5) = cosd(180)*R(:,:,1)+sind(180)*R(:,:,2);
        R(:,:,6) = cosd(225)*R(:,:,1)+sind(225)*R(:,:,2);
        R(:,:,7) = cosd(270)*R(:,:,1)+sind(270)*R(:,:,2);
        R(:,:,7) = cosd(315)*R(:,:,1)+sind(315)*R(:,:,2);
        FM = max(R,[],3);
        FM = mean2(FM);

    case 'SFRQ' % Spatial frequency (Eskicioglu95)
        Ix = Image;
        Iy = Image;
        Ix(:,1:end-1) = diff(Image, 1, 2);
        Iy(1:end-1,:) = diff(Image, 1, 1);
        FM = mean2(sqrt(double(Iy.^2+Ix.^2)));

    case 'TENG'% Tenengrad (Krotkov86)
        Sx = fspecial('sobel');
        Gx = imfilter(double(Image), Sx, 'replicate', 'conv');
        Gy = imfilter(double(Image), Sx', 'replicate', 'conv');
        FM = Gx.^2 + Gy.^2;
        FM = mean2(FM);

    case 'TENV' % Tenengrad variance (Pech2000)
        Sx = fspecial('sobel');
        Gx = imfilter(double(Image), Sx, 'replicate', 'conv');
        Gy = imfilter(double(Image), Sx', 'replicate', 'conv');
        G = Gx.^2 + Gy.^2;
        FM = std2(G)^2;

    case 'VOLA' % Vollath's correlation (Santos97)
        Image = double(Image);
        I1 = Image; I1(1:end-1,:) = Image(2:end,:);
        I2 = Image; I2(1:end-2,:) = Image(3:end,:);
        Image = Image.*(I1-I2);
        FM = mean2(Image);

    case 'WAVS' %Sum of Wavelet coeffs (Yang2003)
        [C,S] = wavedec2(Image, 1, 'db6');
        H = wrcoef2('h', C, S, 'db6', 1);   
        V = wrcoef2('v', C, S, 'db6', 1);   
        D = wrcoef2('d', C, S, 'db6', 1);   
        FM = abs(H) + abs(V) + abs(D);
        FM = mean2(FM);

    case 'WAVV' %Variance of  Wav...(Yang2003)
        [C,S] = wavedec2(Image, 1, 'db6');
        H = abs(wrcoef2('h', C, S, 'db6', 1));
        V = abs(wrcoef2('v', C, S, 'db6', 1));
        D = abs(wrcoef2('d', C, S, 'db6', 1));
        FM = std2(H)^2+std2(V)+std2(D);

    case 'WAVR'
        [C,S] = wavedec2(Image, 3, 'db6');
        H = abs(wrcoef2('h', C, S, 'db6', 1));   
        V = abs(wrcoef2('v', C, S, 'db6', 1));   
        D = abs(wrcoef2('d', C, S, 'db6', 1)); 
        A1 = abs(wrcoef2('a', C, S, 'db6', 1));
        A2 = abs(wrcoef2('a', C, S, 'db6', 2));
        A3 = abs(wrcoef2('a', C, S, 'db6', 3));
        A = A1 + A2 + A3;
        WH = H.^2 + V.^2 + D.^2;
        WH = mean2(WH);
        WL = mean2(A);
        FM = WH/WL;
    otherwise
        error('Unknown measure %s',upper(Measure))
end
 end
%************************************************************************
function fm = AcMomentum(Image)
[M N] = size(Image);
Hist = imhist(Image)/(M*N);
Hist = abs((0:255)-255*mean2(Image))'.*Hist;
fm = sum(Hist);
end

%******************************************************************
function fm = DctRatio(M)
MT = dct2(M).^2;
fm = (sum(MT(:))-MT(1,1))/MT(1,1);
end

%************************************************************************
function fm = ReRatio(M)
M = dct2(M);
fm = (M(1,2)^2+M(1,3)^2+M(2,1)^2+M(2,2)^2+M(3,1)^2)/(M(1,1)^2);
end
%******************************************************************

Несколько примеров версий OpenCV:

// OpenCV port of 'LAPM' algorithm (Nayar89)
double modifiedLaplacian(const cv::Mat& src)
{
    cv::Mat M = (Mat_<double>(3, 1) << -1, 2, -1);
    cv::Mat G = cv::getGaussianKernel(3, -1, CV_64F);

    cv::Mat Lx;
    cv::sepFilter2D(src, Lx, CV_64F, M, G);

    cv::Mat Ly;
    cv::sepFilter2D(src, Ly, CV_64F, G, M);

    cv::Mat FM = cv::abs(Lx) + cv::abs(Ly);

    double focusMeasure = cv::mean(FM).val[0];
    return focusMeasure;
}

// OpenCV port of 'LAPV' algorithm (Pech2000)
double varianceOfLaplacian(const cv::Mat& src)
{
    cv::Mat lap;
    cv::Laplacian(src, lap, CV_64F);

    cv::Scalar mu, sigma;
    cv::meanStdDev(lap, mu, sigma);

    double focusMeasure = sigma.val[0]*sigma.val[0];
    return focusMeasure;
}

// OpenCV port of 'TENG' algorithm (Krotkov86)
double tenengrad(const cv::Mat& src, int ksize)
{
    cv::Mat Gx, Gy;
    cv::Sobel(src, Gx, CV_64F, 1, 0, ksize);
    cv::Sobel(src, Gy, CV_64F, 0, 1, ksize);

    cv::Mat FM = Gx.mul(Gx) + Gy.mul(Gy);

    double focusMeasure = cv::mean(FM).val[0];
    return focusMeasure;
}

// OpenCV port of 'GLVN' algorithm (Santos97)
double normalizedGraylevelVariance(const cv::Mat& src)
{
    cv::Scalar mu, sigma;
    cv::meanStdDev(src, mu, sigma);

    double focusMeasure = (sigma.val[0]*sigma.val[0]) / mu.val[0];
    return focusMeasure;
}

Нет гарантий того, меры - лучший выбор для вашей проблемы, но если вы отследите документы, связанные с этими мерами, они могут дать вам больше информации. Надеюсь, вы найдете код полезным! Я знаю, что сделал.

66
ответ дан mevatron 21 August 2018 в 05:55
поделиться
  • 1
    в tenengrad алгоритме, что будет номинальным значением для kSize? – mans 29 August 2016 в 08:13
  • 2
    @mans Обычно я использую 3, 5 или 7 в зависимости от разрешения изображения. Если вы обнаружите, что вам нужно идти выше этого, вы можете захотеть взглянуть на понижающую дискретизацию изображения. – mevatron 3 October 2016 в 01:09

Один из способов, который я использую в настоящее время, измеряет распространение ребер в изображении. Посмотрите на эту статью:

@ARTICLE{Marziliano04perceptualblur,
    author = {Pina Marziliano and Frederic Dufaux and Stefan Winkler and Touradj Ebrahimi},
    title = {Perceptual blur and ringing metrics: Application to JPEG2000,” Signal Process},
    journal = {Image Commun},
    year = {2004},
    pages = {163--172} }

Обычно это за платой, но я видел несколько бесплатных копий. В основном, они определяют вертикальные края изображения, а затем измеряют ширину этих краев. Усреднение ширины дает окончательный результат оценки размытия для изображения. Более широкие края соответствуют размытым изображениям и наоборот.

Эта проблема относится к области оценки качества безреференсного изображения . Если вы посмотрите на Google Scholar, вы получите много полезных ссылок.

EDIT

Вот график оценок размытости, полученных для 5 изображений в сообщении nikie. Более высокие значения соответствуют большему размытию. Я использовал гауссовский фильтр с фиксированным размером 11x11 и менял стандартное отклонение (используя команду femfmememagick для получения размытых изображений).

enter image description here [/g1]

Если вы сравниваете изображения разных размеров, не забудьте нормализовать ширину изображения, так как большие изображения будут иметь более широкие края.

Наконец, значительная проблема заключается в различии между художественным размытием и нежелательным размытием (вызванным фокусным промахом, сжатием, относительным движением объекта к камере), но это выходит за рамки простых подходов, подобных этому. Для примера художественного размытия взгляните на изображение Ленны: отражение Ленны в зеркале размыто, но ее лицо полностью сосредоточено. Это способствует более высокой оценке размытия для изображения Lenna.

9
ответ дан misha 21 August 2018 в 05:55
поделиться

Это то, что я делаю в Opencv для определения качества фокусировки в регионе:

Mat grad;
int scale = 1;
int delta = 0;
int ddepth = CV_8U;
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
/// Gradient X
Sobel(matFromSensor, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
/// Gradient Y
Sobel(matFromSensor, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
cv::Scalar mu, sigma;
cv::meanStdDev(grad, /* mean */ mu, /*stdev*/ sigma);
focusMeasure = mu.val[0] * mu.val[0];
0
ответ дан Nadav B 21 August 2018 в 05:55
поделиться

Еще один очень простой способ оценить резкость изображения - использовать фильтр Laplace (или LoG) и просто выбрать максимальное значение. Использование надежной меры, такой как 99,9% квантиль, вероятно, лучше, если вы ожидаете шума (т. Е. Выбираете N-высокий контраст, а не самый высокий контраст). Если вы ожидаете изменения яркости изображения, вы также должны включить шаг предварительной обработки для нормализации яркости / контраст (например, выравнивание гистограммы).

Я реализовал предложение Саймона и этот в Mathematica и попробовал его на нескольких тестовых изображениях:

test images [/g0]

Первый тест размывает тестовые изображения с использованием гауссовского фильтра с различным размером ядра, затем вычисляет БПФ размытого изображения и принимает среднее значение на 90% самых высоких частот:

testFft[img_] := Table[
  (
   blurred = GaussianFilter[img, r];
   fft = Fourier[ImageData[blurred]];
   {w, h} = Dimensions[fft];
   windowSize = Round[w/2.1];
   Mean[Flatten[(Abs[
       fft[[w/2 - windowSize ;; w/2 + windowSize, 
         h/2 - windowSize ;; h/2 + windowSize]]])]]
   ), {r, 0, 10, 0.5}]

Результат в логарифмическом графике:

fft result [/g1]

5 строк представляют собой 5 тестовых изображений, ось X представляет собой гауссовский радиус фильтра. Графики уменьшаются, поэтому БПФ является хорошей мерой для резкости.

Это код для оценки вероятности «высшей точки»: он просто применяет LoG-фильтр и возвращает самый яркий пиксель в результате фильтра:

testLaplacian[img_] := Table[
  (
   blurred = GaussianFilter[img, r];
   Max[Flatten[ImageData[LaplacianGaussianFilter[blurred, 1]]]];
   ), {r, 0, 10, 0.5}]

Результат в логарифмическом plot:

laplace result [/g2]

Распространение для не размытых изображений здесь немного лучше (2.5 против 3.3), главным образом потому, что этот метод использует только самые сильные контрастность изображения, тогда как БПФ является, по существу, средним по всему изображению. Функции также уменьшаются быстрее, поэтому может быть проще установить «размытый» порог.

132
ответ дан Niki 21 August 2018 в 05:55
поделиться
  • 1
    +1. Не могли бы вы предоставить легенду для своих сюжетов? :П – misha 16 October 2011 в 04:55
  • 2
    Что, если я померил местное размытие. А именно, фотография имеет области, где она размыта и где она резкая. Я хочу иметь карту, которая оценивает уровень размытия на пиксель. – Royi 2 November 2012 в 09:49
  • 3
    @Drazick: Я не уверен, что это возможно. Например, посмотрите на изображение Лены: есть большие области, где нет контраста (например, кожи Лены), хотя область находится в фокусе. Я не могу придумать, как определить, является ли такая гладкая область «размытой» или отличить ее от области вне фокуса. Вы должны задать это как отдельный вопрос (возможно, на DSP.SE). Возможно, у кого-то есть лучшие идеи. – Niki 2 November 2012 в 10:28
  • 4
    Он подходит для размытия движения? или только для размытия, как гауссово? – mrgloom 3 June 2013 в 07:01
  • 5
    @chappjc Конечно! pastebin.com/VuYshqhk – pparescasellas 16 January 2014 в 10:43

Исходя из ответа Найка. Его простота для реализации метода на основе лапласа с помощью opencv:

short GetSharpness(char* data, unsigned int width, unsigned int height)
{
    // assumes that your image is already in planner yuv or 8 bit greyscale
    IplImage* in = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
    IplImage* out = cvCreateImage(cvSize(width,height),IPL_DEPTH_16S,1);
    memcpy(in->imageData,data,width*height);

    // aperture size of 1 corresponds to the correct matrix
    cvLaplace(in, out, 1);

    short maxLap = -32767;
    short* imgData = (short*)out->imageData;
    for(int i =0;i<(out->imageSize/2);i++)
    {
        if(imgData[i] > maxLap) maxLap = imgData[i];
    }

    cvReleaseImage(&in);
    cvReleaseImage(&out);
    return maxLap;
}

Вернет короткое указание, указывающее на обнаруженную максимальную резкость, которая, основываясь на моих тестах на образцах реального мира, является довольно хорошим индикатором того, если камера находится в фокусе или нет. Неудивительно, что нормальные значения зависят от сцены, но много меньше, чем метод FFT, который должен иметь значение ложной положительной скорости, чтобы быть полезным в моем приложении.

28
ответ дан Yaur 21 August 2018 в 05:55
поделиться
  • 1
    Каким будет пороговое значение, чтобы сказать, что изображение размыто? Я протестировал его. Но это показывает некоторые переменные результаты. Не могли бы вы помочь мне в этом, чтобы установить порог? – 2vision2 7 February 2013 в 08:28
  • 2
    Также попробовал ваше предложение, но цифры, которые я получаю, немного случайны. Если я начну новый вопрос относительно этой конкретной реализации, не могли бы вы взглянуть? \ – Stpn 3 June 2013 в 20:28
  • 3
    @stpn Правильный порог зависит от сцены. В моем приложении (CCTV) я использую порог по умолчанию 300. Для камер, где это мало кто из поддержки, изменит настроенное значение для этой конкретной камеры. – Yaur 3 June 2013 в 22:32
  • 4
    почему «maxLap = -32767;» ? – Clement Prem 26 February 2015 в 12:34
  • 5
    Мы ищем самый высокий контраст, так как мы работаем с подписанными шортами -32767 - это самое низкое возможное значение. Его было 2,5 года с тех пор, как я написал этот код, но у IIRC у меня были проблемы с использованием 16U. – Yaur 28 February 2015 в 08:03
Другие вопросы по тегам:

Похожие вопросы: