Czy istnieje sposób na wykrycie rozmycia obrazu?

Zastanawiałem się, czy jest sposób, aby określić, czy obraz jest rozmyty, czy nie, analizując dane obrazu.

Author: Sam, 2011-10-14

12 answers

Tak. Oblicz fft i przeanalizuj wynik. Transformata Fouriera mówi, które częstotliwości są obecne na obrazie. Jeśli istnieje mała ilość wysokich częstotliwości, obraz jest rozmyty.

Zdefiniowanie terminów "niski" i "wysoki" zależy od Ciebie.

Edytuj : jak wspomniano w komentarzach, jeśli chcesz, aby pojedynczy float reprezentował rozmycie danego obrazu, musisz wypracować odpowiednią metrykę.

Nikie ' s answer provide such a metric. Połączenie obrazu z jądrem Laplacian:

   1
1 -4  1
   1

I użyj solidnej maksymalnej metryki na wyjściu, aby uzyskać liczbę, której możesz użyć do progowania. Staraj się unikać wygładzania zbyt dużo obrazów przed obliczeniami Laplacian, bo tylko dowiesz się, że wygładzony obraz jest rzeczywiście rozmazany :-).

 108
Author: Simon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:13

Innym bardzo prostym sposobem oszacowania ostrości obrazu jest użycie filtra Laplace (lub LoG) i po prostu wybranie maksymalnej wartości. Użycie solidnej miary, takiej jak kwantyl 99.9%, jest prawdopodobnie lepsze, jeśli spodziewasz się szumu (tj. wybranie n-tego najwyższego kontrastu zamiast najwyższego kontrastu.) Jeśli spodziewasz się różnej jasności obrazu, powinieneś również uwzględnić etap wstępnego przetwarzania w celu normalizacji jasności/kontrastu obrazu (np. wyrównanie histogramu).

Zaimplementowałem sugestię Simona i ten w Mathematica, i wypróbował go na kilku testowych zdjęciach:

zdjęcia testowe

Pierwszy test rozmywa obrazy testowe za pomocą filtra Gaussa o różnej wielkości jądra, następnie oblicza FFT rozmytego obrazu i przyjmuje średnią z 90% najwyższych częstotliwości:

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}]

Wynik wykresu logarytmicznego:

wynik fft

5 linii reprezentuje 5 obrazów testowych, oś X reprezentuje Promień filtra Gaussa. Wykresy maleją, więc FFT jest dobrym pomiar ostrości.

Jest to kod estymatora rozmycia "najwyższego dziennika": po prostu stosuje filtr dziennika i zwraca najjaśniejszy piksel w wyniku filtra:

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

Wynik wykresu logarytmicznego:

wynik laplace ' a

Spread dla nie rozmytych obrazów jest tutaj nieco lepszy (2,5 vs 3,3), głównie dlatego, że ta metoda wykorzystuje tylko najsilniejszy kontrast na obrazie, podczas gdy FFT jest zasadniczo średnią dla całego obrazu. Funkcje są również zmniejsza się szybciej, więc może być łatwiej ustawić próg "rozmyty".

 136
Author: Niki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 13:59:29

Podczas pracy z obiektywem auto-focus natknąłem się na ten bardzo przydatny zestaw algorytmów do wykrywania ostrości obrazu. Jest zaimplementowany w MATLAB, ale większość funkcji jest dość łatwa do przeniesienia do OpenCV za pomocą filter2D .

Jest to w zasadzie implementacja wielu algorytmów pomiaru ostrości. Jeśli chcesz przeczytać oryginalne prace, w kodzie znajdują się odniesienia do autorów algorytmów. [2012-02-09 19: 42] Analiza focus measure operators for shape from focus (SFF) daje świetny przegląd wszystkich tych miar, jak również ich wydajności (zarówno pod względem szybkości i dokładności, jak w przypadku SFF).

EDIT: Dodano kod MATLAB na wypadek, gdyby link umarł.

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
%******************************************************************

Kilka przykładów wersji 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;
}

Brak gwarancji, czy te środki są najlepszym wyborem dla Twojego problemu, ale jeśli wyśledzisz dokumenty związane z tymi środkami, mogą dać ci więcej wglądu. Mam nadzieję, że uznasz kod za przydatny! Wiem.

 66
Author: mevatron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 22:16:23

/ Align = "center" bgcolor = "# e0ffe0 " / Cesarz Chin / / align = center / Jego proste wdrożenie metody opartej na laplacianie z 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;
}

Zwróci Skrót wskazujący maksymalną wykrytą ostrość, co na podstawie moich testów na rzeczywistych próbkach, jest całkiem dobrym wskaźnikiem, czy kamera jest w centrum uwagi, czy nie. Nic dziwnego, że wartości normalne są zależne od sceny, ale znacznie mniej niż metoda FFT, która ma wysoki wskaźnik fałszywie dodatni, aby być użytecznym w mojej aplikacji.

 28
Author: Yaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-01 19:41:44

Wymyśliłem zupełnie inne rozwiązanie. Musiałem przeanalizować klatki wideo, aby znaleźć najostrzejszy w każdej (x) klatce. W ten sposób wykryłbym rozmycie w ruchu i / lub nieostre obrazy.

Skończyłem z Canny Edge detection i uzyskałem bardzo dobre wyniki z prawie każdym rodzajem wideo (przy metodzie nikie ' ego miałem problemy z cyfrowymi filmami VHS i ciężkimi filmami z przeplotem).

Zoptymalizowałem wydajność, ustawiając region of interest (ROI) na oryginalny obraz.

Używając 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
Author: Goldorak84,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 15:34:43

Dzięki nikie za świetną sugestię Laplace ' a. dokumenty OpenCV wskazywały mi ten sam kierunek: korzystanie z Pythona, cv2 (opencv 2.4.10) i numpy...

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

Wynik jest pomiędzy 0-255. Znalazłem coś ponad 200ish jest bardzo ostrości, i przez 100, to jest zauważalnie rozmyte. max nigdy nie dostaje dużo poniżej 20, nawet jeśli jest całkowicie rozmyte.

 13
Author: ggez44,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-26 02:52:00

Jeden ze sposobów, którego obecnie używam, mierzy rozstaw krawędzi na obrazie. Poszukaj tego papieru:

@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} }
Zazwyczaj jest za paywall, ale widziałem kilka darmowych kopii. Zasadniczo lokalizują pionowe krawędzie obrazu, a następnie mierzą ich szerokość. Uśrednianie szerokości daje ostateczny wynik szacowania rozmycia dla obrazu. Szersze krawędzie odpowiadają zamazanym obrazom i odwrotnie.

Ten problem należy do pola obraz bez odniesienia ocena jakości . Jeśli poszukasz go w Google Scholar, otrzymasz wiele przydatnych referencji.

EDIT

To jest wykres oszacowań rozmycia uzyskanych dla 5 zdjęć w poście nikie ' ego. Wyższe wartości odpowiadają większemu rozmyciu. Użyłem filtra Gaussa o stałym rozmiarze 11x11 i zmieniłem odchylenie standardowe (używając polecenia imagemagick convert, Aby uzyskać rozmyte obrazy).

Tutaj wpisz opis obrazka

Jeśli porównujesz obrazy o różnych rozmiarach, nie zapomnij znormalizuj według szerokości obrazu, ponieważ większe obrazy będą miały szersze krawędzie.

Wreszcie, istotnym problemem jest rozróżnienie pomiędzy artystycznym rozmyciem i niepożądanym rozmyciem( spowodowanym brakiem ostrości, kompresją, względnym ruchem obiektu w aparacie), ale to wykracza poza proste podejścia, takie jak to. Dla przykładu artystycznego rozmycia, spójrz na obraz Lenny: odbicie Lenny w lustrze jest rozmyte, ale jej twarz jest idealnie skupiona. Przyczynia się to do większego rozmycia oszacowanie dla obrazu Lenna.

 9
Author: mpenkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-16 04:51:04

Odpowiedzi powyżej wyjaśniają wiele rzeczy, ale myślę, że warto dokonać pojęciowego rozróżnienia.

Co zrobić, jeśli zrobisz perfekcyjnie na ostrości zdjęcie rozmytego obrazu?

Problem wykrywania rozmycia jest dobrze upozorowany tylko wtedy, gdy maszodniesienie . Jeśli potrzebujesz zaprojektować np. system auto-focus, porównujesz sekwencję zdjęć wykonanych z różnymi stopniami rozmycia lub wygładzania i próbujesz znaleźć punkt minimalnego rozmycia w tym zestawie. I innymi słowy, musisz odwołać się do różnych obrazów za pomocą jednej z technik zilustrowanych powyżej (zasadniczo-z różnymi możliwymi poziomami wyrafinowania w podejściu-szukając jednego obrazu o najwyższej zawartości wysokiej częstotliwości).

 3
Author: Emerald Weapon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-12 16:04:41

Wypróbowałem rozwiązanie oparte na filtrze Laplacian z tego postu . To mi nie pomogło. Wypróbowałem więc rozwiązanie z tego posta i było dobre dla mojego przypadku (ale jest powolne):

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))

Mniej rozmyte zdjęcie ma maksymalną wartość sum!

Możesz również dostroić prędkość i dokładność, zmieniając krok, np.

Ta część

for x in range(width - 1):

Możesz zastąpić tym

for x in range(0, width - 1, 10):
 2
Author: Exterminator13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-11 14:05:10

Kod Matlab dwóch metod, które zostały opublikowane w cenionych czasopismach (IEEE Transactions on Image Processing) są dostępne tutaj: https://ivulab.asu.edu/software

Sprawdź algorytmy CPBDM i JNBM. Jeśli sprawdzisz kod, nie jest to trudne do przeniesienia i nawiasem mówiąc jest on oparty na metodzie Marzialiano jako podstawowej funkcji.

 1
Author: Marco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-04 17:25:52

Zaimplementowałem go używając fft w Matlabie i sprawdzając histogram średniej obliczeniowej FFT i std, ale można również wykonać funkcję fit

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
Author: user3452134,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 07:50:58

To właśnie robię w Opencv, aby wykryć jakość ostrości w regionie:

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
Author: Nadav B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 15:16:18