क्या यह पता लगाने का कोई तरीका है कि क्या कोई छवि धुंधली है?


203

मैं सोच रहा था कि क्या यह निर्धारित करने का कोई तरीका है कि छवि डेटा का विश्लेषण करके धुंधली है या नहीं।


7
संबंधित प्रश्न जिसमें एक अच्छा उत्तर है, लेकिन एक अधिक शामिल प्रश्न सूत्रीकरण भी है। stackoverflow.com/questions/5180327/…
लेनार्ट रोलैंड

1
इसके बहुत बुरे जवाब भी हैं।
जॉन शेडलेस्की

जवाबों:


133

हाँ यही है। फास्ट फूरियर रूपांतरण की गणना करें और परिणाम का विश्लेषण करें। फूरियर रूपांतरण आपको बताता है कि छवि में कौन सी आवृत्तियां मौजूद हैं। यदि उच्च आवृत्तियों की कम मात्रा है, तो छवि धुंधली है।

'कम' और 'उच्च' शब्दों को परिभाषित करना आप पर निर्भर है।

संपादित करें :

जैसा कि टिप्पणियों में कहा गया है, यदि आप किसी दिए गए चित्र के धुंधलेपन का प्रतिनिधित्व करते हुए एकल फ्लोट चाहते हैं, तो आपको एक उपयुक्त मीट्रिक का उपयोग करना होगा।

nikie का जवाब इस तरह की मीट्रिक प्रदान करता है। एक लाप्लास कर्नेल के साथ छवि का रूपांतरण करें:

   1
1 -4  1
   1

और आउटपुट पर एक मजबूत अधिकतम मीट्रिक का उपयोग करें एक संख्या प्राप्त करने के लिए जिसे आप थ्रेसहोल्डिंग के लिए उपयोग कर सकते हैं। लाप्लासियन की गणना करने से पहले बहुत अधिक छवियों को चौरसाई करने से बचने की कोशिश करें, क्योंकि आपको केवल यह पता चलेगा कि एक चिकनी छवि वास्तव में धुंधली है :-)।


9
केवल समस्या 'कम' और 'उच्च' दृश्य निर्भर भी हैं। +1
केनी

4
जब तक आपकी छवि चक्रीय नहीं होती है, तो आप आमतौर पर छवि की सीमाओं पर तेज किनारों होंगे जो बहुत उच्च आवृत्तियों की ओर ले जाते हैं
निकी

2
आप आमतौर पर इस प्रभाव से बचने के लिए अपनी छवि का विस्तार करते हैं। आप स्थानीय fft की गणना करने के लिए छोटी खिड़कियों का भी उपयोग कर सकते हैं।
सिमोन बर्गोट

6
केवल एक बिंदु जो बेहद महत्वपूर्ण है, आपको यह जानना होगा (कम से कम मोटे तौर पर) आपकी अपेक्षित पूर्व-धुंधली छवि (आवृत्ति) क्या थी। यह सच है क्योंकि आवृत्ति स्पेक्ट्रम मूल छवि के समय की है कि धुंधला फिल्टर की जा रही है। इस प्रकार, यदि मूल छवि में पहले से ही मुख्य रूप से कम आवृत्तियों थे, तो आप यह कैसे बता सकते हैं कि यह धुंधला था?
क्रिस ए।

1
यदि आप एक खाली सफेद चार्ट की तस्वीर लेते हैं, तो आपके पास यह बताने का कोई तरीका नहीं है कि छवि धुंधली है या नहीं। मुझे लगता है कि ओपी कुछ पूर्ण तीक्ष्णता माप चाहता है। पूर्वनिर्मित छवि बिल्कुल भी मौजूद नहीं हो सकती है। आपको एक सही मीट्रिक के साथ आने के लिए थोड़ा काम करना होगा, लेकिन इस समस्या के साथ fft मदद कर सकता है। इस परिप्रेक्ष्य में, निकी का जवाब मेरी तुलना में बेहतर है।
साइमन बर्गोट

158

छवि के तीखेपन का अनुमान लगाने का एक और बहुत सरल तरीका है लैप्लस (या एलओजी) फ़िल्टर का उपयोग करना और बस अधिकतम मूल्य चुनना। 99.9% मात्रात्मक जैसे एक मजबूत उपाय का उपयोग करना बेहतर है यदि आप शोर की उम्मीद करते हैं (यानी उच्चतम विपरीत के बजाय एनटीटी-उच्चतम विपरीत उठाते हैं।) यदि आप अलग-अलग छवि चमक की अपेक्षा करते हैं, तो आपको छवि चमक को सामान्य करने के लिए प्रीप्रोसेसिंग चरण भी शामिल करना चाहिए। इसके विपरीत (उदाहरण के लिए हिस्टोग्राम समीकरण)।

मैंने साइमन के सुझाव को लागू किया है और गणितज्ञ में यह एक है, और इसे कुछ परीक्षण छवियों पर आज़माया है:

छवियों का परीक्षण करें

पहला परीक्षण एक अलग कर्नेल आकार के साथ गॉसियन फ़िल्टर का उपयोग करके परीक्षण छवियों को धुंधला करता है, फिर धुंधली छवि के एफएफटी की गणना करता है और 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}]

एक लघुगणकीय साजिश में परिणाम:

नतीजा

5 रेखाएं 5 परीक्षण छवियों का प्रतिनिधित्व करती हैं, एक्स अक्ष गाऊसी फिल्टर त्रिज्या का प्रतिनिधित्व करता है। ग्राफ कम हो रहे हैं, इसलिए एफएफटी तीखेपन के लिए एक अच्छा उपाय है।

यह "उच्चतम LoG" धुंधला आकलनकर्ता के लिए कोड है: यह केवल LoG फ़िल्टर लागू करता है और फ़िल्टर परिणाम में सबसे चमकदार पिक्सेल लौटाता है:

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

एक लघुगणकीय साजिश में परिणाम:

परिणाम

संयुक्त-धुंधली छवियों के लिए प्रसार यहां थोड़ा बेहतर है (2.5 बनाम 3.3), मुख्य रूप से क्योंकि यह विधि केवल छवि में सबसे मजबूत विपरीत का उपयोग करती है, जबकि एफएफटी अनिवार्य रूप से पूरी छवि पर एक मतलब है। फ़ंक्शंस भी तेज़ी से कम हो रहे हैं, इसलिए "धुंधली" सीमा निर्धारित करना आसान हो सकता है।


1
क्या होगा अगर मैं स्थानीय कलंक के उपाय के बाद हूं। अर्थात्, एक फोटो में ऐसे क्षेत्र हैं जहाँ यह धुंधला है और जहाँ यह तेज है। मैं एक नक्शा बनाना चाहता हूं जो पिक्सेल के प्रति धुंधला स्तर का अनुमान लगाता है।
रॉय

4
@ ड्रेक: मुझे यकीन नहीं है कि अगर यह भी संभव है। उदाहरण के लिए, लीना छवि को देखें: ऐसे बड़े क्षेत्र हैं जहां कोई विपरीत नहीं है (जैसे लीना की त्वचा) हालांकि यह क्षेत्र फोकस में है। मैं यह बताने का कोई तरीका नहीं सोच सकता कि क्या इस तरह का एक चिकना क्षेत्र "धुंधली" है, या इसे एक आउट-ऑफ-फोकस क्षेत्र से अलग करने के लिए। आपको इसे एक अलग प्रश्न के रूप में पूछना चाहिए (शायद DSP.SE पर)। हो सकता है कि किसी और के पास बेहतर विचार हों।
निक्की

1
क्या यह गति धुंधला के लिए उपयुक्त है? या केवल गॉसियन की तरह धब्बा के लिए?
मर्ग्लोम

@pparescasellas क्या आप अपने कार्यान्वयन को साझा करने के लिए तैयार होंगे। मैं उन्हें देखने के लिए उत्सुक हूँ।
चापजैक

@ जॉनबॉय मुझे लगता है कि आप का मतलब है पेपरसैसेलास
चाप्जक

79

एक ऑटो-फोकस लेंस के साथ कुछ काम के दौरान, मुझे छवि फोकस का पता लगाने के लिए एल्गोरिदम का यह बहुत उपयोगी सेट आया । यह MATLAB में लागू किया गया है, लेकिन अधिकांश कार्य फ़िल्टर 2 डी के साथ ओपनसीवी में पोर्ट करना काफी आसान है ।

यह मूल रूप से कई फोकस माप एल्गोरिदम का एक सर्वेक्षण कार्यान्वयन है। यदि आप मूल पत्रों को पढ़ना चाहते हैं, तो कोड में एल्गोरिदम के लेखकों के संदर्भ प्रदान किए गए हैं। पर्टुज़ द्वारा 2012 का पेपर, एट अल। फोकस (एसएफएफ) से आकार के लिए फोकस माप ऑपरेटरों का विश्लेषण इन सभी उपायों के साथ-साथ उनके प्रदर्शन (गति और सटीकता के संदर्भ में एसएफएफ पर लागू होता है) की एक महान समीक्षा देता है।

संपादित करें: लिंक मर जाने की स्थिति में 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;
}

इस बात की कोई गारंटी नहीं है कि ये उपाय आपकी समस्या के लिए सबसे अच्छा विकल्प हैं या नहीं, लेकिन यदि आप इन उपायों से जुड़े कागजात को ट्रैक करते हैं, तो वे आपको अधिक जानकारी दे सकते हैं। आशा है कि आपको कोड उपयोगी लगेगा! मुझे पता है मैंने किया।


टेनग्रैड एल्गोरिथ्म में, kSize के लिए एक मामूली मूल्य क्या होगा?
मनुष्य

@ आम तौर पर मैं छवि के संकल्प के आधार पर 3, 5 या 7 का उपयोग करता हूं। यदि आप पाते हैं कि आपको इससे अधिक जाने की आवश्यकता है, तो आप छवि को डाउनसम्पलिंग करना चाह सकते हैं।
mevatron

32

नाइके के उत्तर का निर्माण। लैपलैसियन आधारित विधि को ओपनकेव के साथ लागू करने के लिए इसका सीधा:

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

पता चला है कि वास्तविक दुनिया के नमूनों पर मेरे परीक्षणों के आधार पर पता चला है कि एक कैमरा फोकस में है या नहीं, का एक अच्छा संकेत है, जो एक छोटा संकेत है। आश्चर्य की बात नहीं है, सामान्य मूल्य दृश्य निर्भर हैं, लेकिन एफएफटी विधि की तुलना में बहुत कम है जो मेरे आवेदन में उपयोगी होने के लिए झूठी सकारात्मक दर के उच्च है।


छवि को धूमिल कहने के लिए थ्रेशहोल्ड मान क्या होगा? मैंने इसका परीक्षण किया है। लेकिन इसके कुछ अलग परिणाम दिखाई दे रहे हैं। क्या आप कृपया मुझे इस सीमा को निर्धारित करने में मदद कर सकते हैं?
संशोधन 2

अपने सुझाव को भी आजमाया, लेकिन मुझे जो नंबर मिले हैं, वे थोड़े यादृच्छिक हैं। अगर मैं इस विशेष कार्यान्वयन के संबंध में एक नया सवाल शुरू करते हैं, आप एक बार देख ले करना चाहेंगे \?
Stpn

@stpn सही सीमा दृश्य निर्भर है। अपने आवेदन में (सीसीटीवी) मैं 300 की एक डिफ़ॉल्ट सीमा का उपयोग कर रहा हूं। उन कैमरों के लिए जहां समर्थन से किसी को कम करना है, उस विशेष कैमरे के लिए कॉन्फ़िगर किए गए मान को बदल देगा।
योर

"maxLap = -32767" क्यों है? ?
क्लेमेंट प्रेम

हम उच्चतम कंट्रास्ट की तलाश कर रहे हैं और चूंकि हम हस्ताक्षरित शॉर्ट्स के साथ काम कर रहे हैं -32767 सबसे कम संभव मूल्य है। इसका 2.5 साल हो गया है जब मैंने उस कोड को लिखा था लेकिन IIRC I में 16U का उपयोग करने के मुद्दे थे।
योर

23

मैं पूरी तरह से अलग समाधान के साथ आया था। मैं हर (एक्स) फ्रेम में सबसे तेज एक खोजने के लिए वीडियो अभी भी तख्ते का विश्लेषण करने की जरूरत है। इस तरह, मैं गति छवियों और / या फ़ोकस छवियों से बाहर का पता लगाऊंगा।

मैं कैनी एज डिटेक्शन का उपयोग कर समाप्त हो गया और मुझे लगभग हर तरह के वीडियो के साथ बहुत अच्छे परिणाम मिले (निक्की की विधि के साथ, मुझे डिजिटल वीएचएस वीडियो और भारी इंटरलेस्ड वीडियो के साथ समस्या थी)।

मैंने मूल छवि पर ब्याज क्षेत्र (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

उस महान लाप्लास सुझाव के लिए धन्यवाद निक्की। OpenCV डॉक्स ने मुझे एक ही दिशा में इंगित किया: अजगर, cv2 (opencv 2.4.10), और अंक का उपयोग ...

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

परिणाम 0-255 के बीच है। मैंने पाया कि 200ish से अधिक कुछ भी फ़ोकस में है, और 100 तक, यह बिल्कुल धुंधला है। पूरी तरह से धुंधला होने पर भी अधिकतम कभी भी 20 से कम नहीं होता है।


3
मुझे अपनी 3 तस्वीरों के लिए 255 मिले। और एक पूरी तरह से केंद्रित फोटो के लिए मुझे 108 मिली। इसलिए, मुझे लगता है कि विधि की प्रभावशीलता कुछ पर निर्भर करती है।
विंडराइडर

@WindWider से सहमत हैं। नमूना छवि जहां यह विफल होती है यह छवि है मुझे लगता है कि इसका कारण यह है कि भले ही छवि अस्थिर है, छवि के विपरीत और पिक्सेल के बीच संबंधित तीव्रता के अंतर बड़े हैं, जिसके कारण लाप्लासियन मान अपेक्षाकृत बड़े हैं। अगर मैं गलत हूं कृपया मुझे सही।
रेशम वाधवा

@ReshamWadhwa cc WindRider - डिट्टो - इसे ठीक करने के बारे में कोई विचार ??
jtlz2

@ ggez44 यह मेरा पसंदीदा उत्तर है - लेकिन मान छवि में पिक्सेल की संख्या का एक कार्य है। क्या आप जानते हैं कि सैद्धांतिक रूप से यह कैसे होता है? मैं इसे एक नए सवाल के रूप में पूछ सकता हूं, लेकिन इसकी शूटिंग खत्म होने की संभावना है। धन्यवाद!
jtlz2

10

एक तरीका है जो मैं वर्तमान में उपयोग कर रहा हूँ छवि में किनारों के प्रसार। इस पेपर को देखें:

@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 विद्वान पर देखते हैं, तो आपको बहुत सारे उपयोगी संदर्भ मिलेंगे।

संपादित करें

यहाँ निक्की के पोस्ट में 5 छवियों के लिए प्राप्त धुंधला अनुमानों का एक भूखंड है। उच्च मूल्य अधिक धुंधला के अनुरूप हैं। मैंने एक निश्चित आकार के 11x11 गाऊसी फ़िल्टर का उपयोग किया और मानक विचलन को अलग किया ( convertधुंधली छवियों को प्राप्त करने के लिए इमेजमैगिक के आदेश का उपयोग करके )।

यहां छवि विवरण दर्ज करें

यदि आप विभिन्न आकारों की छवियों की तुलना करते हैं, तो छवि की चौड़ाई को सामान्य करने के लिए मत भूलना, क्योंकि बड़ी छवियों में व्यापक किनारे होंगे।

अंत में, एक महत्वपूर्ण समस्या कलात्मक धुंधला और अवांछित धब्बा (फोकस मिस, संपीड़न, कैमरे के अधीन विषय के सापेक्ष गति के कारण) के बीच भेद कर रही है, लेकिन यह इस तरह के सरल दृष्टिकोणों से परे है। कलात्मक धुंधला के उदाहरण के लिए, लेनना छवि पर एक नज़र डालें: दर्पण में लेनना का प्रतिबिंब धुँधला है, लेकिन उसका चेहरा पूरी तरह से ध्यान में है। यह लेनना छवि के लिए एक उच्च धुंधला अनुमान में योगदान देता है।


5

मैंने इस पोस्ट से लाप्लासियन फ़िल्टर पर आधारित समाधान की कोशिश की । इसने मेरी मदद नहीं की। इसलिए, मैंने इस पोस्ट से समाधान की कोशिश की और यह मेरे मामले के लिए अच्छा था (लेकिन धीमा है):

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

4

ऊपर दिए गए उत्तर कई बातों को स्पष्ट करते हैं, लेकिन मुझे लगता है कि यह एक वैचारिक अंतर बनाने के लिए उपयोगी है।

क्या होगा यदि आप एक धुंधली छवि का पूरी तरह से ध्यान केंद्रित चित्र लेते हैं?

जब आपके पास कोई संदर्भ हो, तो धुंधला पता लगाने की समस्या केवल अच्छी तरह से सामने आती है । यदि आपको डिज़ाइन करने की आवश्यकता है, उदाहरण के लिए, एक ऑटो-फ़ोकस सिस्टम, तो आप धुंधला होने, या चौरसाई करने के विभिन्न डिग्री के साथ ली गई छवियों के अनुक्रम की तुलना करते हैं, और आप इस सेट के भीतर न्यूनतम धुंधलापन का बिंदु खोजने की कोशिश करते हैं। अन्य शब्दों को आपको ऊपर वर्णित तकनीकों में से एक का उपयोग करके विभिन्न छवियों को पार करने की आवश्यकता है (मूल रूप से - दृष्टिकोण में शोधन के विभिन्न संभावित स्तरों के साथ - उच्चतम उच्च आवृत्ति सामग्री के साथ एक छवि की तलाश में)।


2
दूसरे शब्दों में, यह एक सापेक्ष धारणा है, यह केवल यह बताना संभव है कि क्या छवि किसी अन्य समान छवि की तुलना में अधिक या कम धुंधली है। यानी यदि इसके FFT में अधिक या कम उच्च आवृत्ति की सामग्री है। विशेष मामला: क्या होगा यदि छवि में अधिकतम और न्यूनतम चमक के साथ आसन्न पिक्सेल हों? उदाहरण के लिए पूरी तरह से सफेद पिक्सेल के बगल में एक पूरी तरह से काला पिक्सेल। इस मामले में यह एक पूर्ण ध्यान केंद्रित है, अन्यथा काले से सफेद तक एक चिकनी संक्रमण होगा। फोटोग्राफी में सही फोकस की संभावना नहीं है, लेकिन सवाल छवि के स्रोत को निर्दिष्ट नहीं करता है (यह कंप्यूटर उत्पन्न हो सकता है)।
बेन

1

दो तरीकों के मतलाब कोड जो उच्च-माना पत्रिकाओं में प्रकाशित किए गए हैं (छवि प्रसंस्करण पर IEEE लेनदेन) यहाँ उपलब्ध हैं: https://ivulab.asu.edu/software

CPBDM और JNBM एल्गोरिदम की जाँच करें। यदि आप कोड की जांच करते हैं तो इसे पोर्ट किया जाना बहुत मुश्किल नहीं है और संयोग से यह मूल विशेषता के रूप में मार्जिलियानो की विधि पर आधारित है।


1

मैंने इसे matlab में fft का उपयोग किया और 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

इस क्षेत्र में फोकस गुणवत्ता का पता लगाने के लिए मैं 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];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.