it-swarm.com.de

Gibt es eine Möglichkeit, zu erkennen, ob ein Bild unscharf ist?

Ich habe mich gefragt, ob es eine Möglichkeit gibt, durch Analyse der Bilddaten festzustellen, ob ein Bild verschwommen ist oder nicht.

172
Sam

Ja, so ist es. Berechnen Sie die schnelle Fourier-Transformation und analysieren Sie das Ergebnis. Die Fourier-Transformation zeigt an, welche Frequenzen im Bild vorhanden sind. Bei niedrigen Frequenzen ist das Bild unscharf.

Die Definition der Begriffe „niedrig“ und „hoch“ liegt bei Ihnen.

Bearbeiten:

Wie in den Kommentaren angegeben, müssen Sie eine geeignete Metrik ermitteln, wenn Sie ein einzelnes Float für Unschärfe eines bestimmten Bildes benötigen. 

Antwort von Nikie Geben Sie eine solche Metrik an. Falte das Bild mit einem Laplace-Kern:

   1
1 -4  1
   1

Verwenden Sie eine robuste maximale Metrik für die Ausgabe, um eine Zahl zu erhalten, die Sie für das Thresholding verwenden können. Vermeiden Sie es, die Bilder vor dem Berechnen des Laplacian zu sehr zu glätten, da Sie nur feststellen, dass ein geglättetes Bild tatsächlich verschwommen ist :-).

113
Simon Bergot

Eine weitere sehr einfache Methode zum Schätzen der Bildschärfe ist die Verwendung eines Laplace- (oder LoG-) Filters und die Auswahl des Maximalwerts. Die Verwendung eines robusten Maßes wie einem 99,9% -Quantil ist wahrscheinlich besser, wenn Sie Rauschen erwarten (dh Sie wählen den N-ten höchsten Kontrast anstelle des höchsten Kontrasts.) Wenn Sie eine unterschiedliche Bildhelligkeit erwarten, sollten Sie auch einen Vorverarbeitungsschritt zur Normalisierung der Bildhelligkeit/Kontrast (zB Histogrammausgleich).

Ich habe Simons Vorschlag und diesen in Mathematica implementiert und an ein paar Testbildern ausprobiert:

test images

Der erste Test verwischt die Testbilder mit einem Gauß-Filter mit unterschiedlicher Kerngröße, berechnet dann die FFT des unscharfen Bildes und ermittelt den Durchschnitt der 90% höchsten Frequenzen:

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

Ergebnis in einer logarithmischen Darstellung:

fft result

Die 5 Linien repräsentieren die 5 Testbilder, die X-Achse den Gaußschen Filterradius. Die Diagramme nehmen ab, daher ist die FFT ein gutes Maß für die Schärfe. 

Dies ist der Code für den Unschärfeschätzer "höchster LoG": Er wendet einfach einen LoG-Filter an und gibt das hellste Pixel im Filterergebnis zurück:

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

Ergebnis in einer logarithmischen Darstellung:

laplace result

Die Streuung für die unscharfen Bilder ist hier etwas besser (2,5 gegenüber 3,3), hauptsächlich weil diese Methode nur den stärksten Kontrast im Bild verwendet, während die FFT im Wesentlichen ein Mittelwert über das gesamte Bild ist. Die Funktionen nehmen ebenfalls schneller ab, sodass es möglicherweise einfacher ist, einen "unscharfen" Schwellenwert einzustellen.

142
Niki

Bei einigen Arbeiten mit einem Autofokusobjektiv bin ich auf diese sehr nützlichen Algorithmen zur Erkennung des Bildfokus gestoßen. Es ist in MATLAB implementiert, aber die meisten Funktionen lassen sich mit filter2D leicht auf OpenCV portieren.

Es ist im Wesentlichen eine Umfrageimplementierung vieler Algorithmen zur Fokusmessung. Wenn Sie die Originalarbeiten lesen möchten, finden Sie im Code Verweise auf die Autoren der Algorithmen. Das Papier von 2012 von Pertuz et al. Die Analyse der Fokusmessungsoperatoren für die Form aus dem Fokus (SFF) gibt einen umfassenden Überblick über alle diese Maße sowie ihre Leistung (sowohl hinsichtlich der Geschwindigkeit als auch der Genauigkeit, wie sie für die SFF angewendet werden).

EDIT: MATLAB-Code hinzugefügt, nur für den Fall, dass der Link nicht mehr funktioniert.

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

Einige Beispiele für OpenCV-Versionen:

// 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;
}

Es gibt keine Garantie dafür, ob diese Maßnahmen die beste Wahl für Ihr Problem sind oder nicht. Wenn Sie jedoch die mit diesen Maßnahmen verbundenen Dokumente ausfindig machen, erhalten Sie möglicherweise mehr Einblick. Ich hoffe, Sie finden den Code nützlich! Ich weiß, dass ich es getan habe.

72
mevatron

Aufbauend auf der Antwort von Nike. Die Implementierung der Laplace-Methode mit opencv ist unkompliziert:

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

Es wird ein Short zurückgegeben, der angibt, dass die maximale Schärfe erkannt wurde. Dies ist ein guter Indikator dafür, ob eine Kamera im Fokus ist oder nicht. Es ist nicht überraschend, dass normale Werte von der Szene abhängig sind, aber viel weniger als bei der FFT-Methode, deren False-Positive-Rate zu hoch ist, um in meiner Anwendung nützlich zu sein.

31
Yaur

Ich hatte eine völlig andere Lösung ... Ich musste Video-Standbilder analysieren, um in jedem (X) -Film das schärfste zu finden. Auf diese Weise würde ich Bewegungsunschärfe und/oder unscharfe Bilder erkennen.

Am Ende habe ich die Canny Edge-Erkennung verwendet und mit fast jeder Art von Video SEHR SEHR gute Ergebnisse erzielt.

Ich habe die Leistung optimiert, indem für das Originalbild eine Region of Interest (ROI) festgelegt wurde.

Verwendung von 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));
}
20
Goldorak84

Danke Nikie für diesen tollen Laplace-Vorschlag. OpenCV docs hat mich in dieselbe Richtung gelenkt: mit Python, CV2 (opencv 2.4.10) und Numpy ...

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

ergebnis liegt zwischen 0-255. Ich habe festgestellt, dass alles, was über 200 ist, sehr scharf ist, und bei 100 ist es merklich verschwommen. Das Maximum wird nie wirklich unter 20, auch wenn es völlig verschwommen ist.

15
ggez44

Eine Methode, die ich gerade verwende, misst die Ausbreitung der Kanten im Bild. Suchen Sie nach diesem Artikel:

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

Es ist normalerweise hinter einer Paywall, aber ich habe einige freie Kopien herum gesehen. Grundsätzlich suchen sie vertikale Kanten in einem Bild und messen dann, wie breit diese Kanten sind. Durch Mitteln der Breite wird das endgültige Unschärfeschätzungsergebnis für das Bild erhalten. Breitere Kanten entsprechen unscharfen Bildern und umgekehrt.

Dieses Problem gehört zum Bereich der No-Reference-Bildqualitätsschätzung. Wenn Sie bei Google Scholar nachschlagen, erhalten Sie viele nützliche Referenzen.

EDIT

Hier ist eine Darstellung der Unschärfeschätzungen, die für die 5 Bilder in Nikies Post erhalten wurden. Höhere Werte entsprechen größerer Unschärfe. Ich verwendete einen 11x11-Gauß-Filter mit fester Größe und variierte die Standardabweichung (mit dem Befehl convert von imagemagick), um unscharfe Bilder zu erhalten.

enter image description here

Vergessen Sie beim Vergleichen von Bildern unterschiedlicher Größe nicht, die Bildbreite zu normalisieren, da größere Bilder breitere Ränder haben. 

Schließlich besteht ein erhebliches Problem in der Unterscheidung zwischen künstlerischer Unschärfe und unerwünschter Unschärfe (verursacht durch Fokusfehler, Kompression und relative Bewegung des Motivs zur Kamera). Ein Beispiel für künstlerische Unschärfe ist ein Blick auf das Lenna-Bild: Lennas Spiegelbild ist verschwommen, aber ihr Gesicht ist vollkommen scharf. Dies trägt zu einer höheren Unschärfe für das Lenna-Bild bei.

9
mpenkov

Die obigen Antworten erklärten viele Dinge, aber ich denke, es ist nützlich, eine begriffliche Unterscheidung vorzunehmen.

Was ist, wenn Sie ein perfekt scharfes Bild eines unscharfen Bildes machen?  

Das Problem der Verwacklungserkennung ist nur dann gut, wenn Sie eine reference haben. Wenn Sie z. B. ein Autofokus-System entwerfen müssen, vergleichen Sie eine Sequenz von Bildern, die mit unterschiedlichen Unschärfen oder Glättungsgraden aufgenommen wurden, und Sie versuchen, den Punkt der minimalen Unschärfe in diesem Satz zu finden. Mit anderen Worten, Sie müssen die verschiedenen Bilder mit einer der oben dargestellten Techniken miteinander verknüpfen (im Grunde - mit verschiedenen möglichen Verfeinerungsgraden im Ansatz - auf der Suche nach einem Bild mit dem höchsten Hochfrequenzinhalt). 

3
Emerald Weapon

Ich habe eine Lösung basierend auf Laplace-Filter aus this post versucht. Es hat mir nicht geholfen. Also habe ich die Lösung aus this post ausprobiert und es war gut für meinen Fall (ist aber langsam):

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

Weniger unscharfes Bild hat maximalen sum-Wert!

Sie können Geschwindigkeit und Genauigkeit auch einstellen, indem Sie den Schritt ändern, z. 

dieser Teil

for x in range(width - 1):

sie können mit diesem ersetzen

for x in range(0, width - 1, 10):
3
Exterminator13

Matlab-Code zweier Methoden, die in angesehenen Zeitschriften (IEEE-Transaktionen zur Bildverarbeitung) veröffentlicht wurden, sind hier verfügbar: https://ivulab.asu.edu/software

Überprüfen Sie die CPBDM- und JNBM-Algorithmen. Wenn Sie den Code überprüfen, ist es nicht sehr schwer, portiert zu werden. Er basiert übrigens auf der Marzialiano-Methode als grundlegendes Merkmal.

1
Marco

ich habe es implementiert, fft in matlab verwenden und das Histogramm des fft-Berechnungsmittelwerts und des std überprüfen

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
user3452134

Das ist, was ich in Opencv mache, um die Fokusqualität in einer Region zu erkennen:

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