मैं सोच रहा था कि क्या यह निर्धारित करने का कोई तरीका है कि छवि डेटा का विश्लेषण करके धुंधली है या नहीं।
मैं सोच रहा था कि क्या यह निर्धारित करने का कोई तरीका है कि छवि डेटा का विश्लेषण करके धुंधली है या नहीं।
जवाबों:
हाँ यही है। फास्ट फूरियर रूपांतरण की गणना करें और परिणाम का विश्लेषण करें। फूरियर रूपांतरण आपको बताता है कि छवि में कौन सी आवृत्तियां मौजूद हैं। यदि उच्च आवृत्तियों की कम मात्रा है, तो छवि धुंधली है।
'कम' और 'उच्च' शब्दों को परिभाषित करना आप पर निर्भर है।
संपादित करें :
जैसा कि टिप्पणियों में कहा गया है, यदि आप किसी दिए गए चित्र के धुंधलेपन का प्रतिनिधित्व करते हुए एकल फ्लोट चाहते हैं, तो आपको एक उपयुक्त मीट्रिक का उपयोग करना होगा।
nikie का जवाब इस तरह की मीट्रिक प्रदान करता है। एक लाप्लास कर्नेल के साथ छवि का रूपांतरण करें:
1
1 -4 1
1
और आउटपुट पर एक मजबूत अधिकतम मीट्रिक का उपयोग करें एक संख्या प्राप्त करने के लिए जिसे आप थ्रेसहोल्डिंग के लिए उपयोग कर सकते हैं। लाप्लासियन की गणना करने से पहले बहुत अधिक छवियों को चौरसाई करने से बचने की कोशिश करें, क्योंकि आपको केवल यह पता चलेगा कि एक चिकनी छवि वास्तव में धुंधली है :-)।
छवि के तीखेपन का अनुमान लगाने का एक और बहुत सरल तरीका है लैप्लस (या एलओजी) फ़िल्टर का उपयोग करना और बस अधिकतम मूल्य चुनना। 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), मुख्य रूप से क्योंकि यह विधि केवल छवि में सबसे मजबूत विपरीत का उपयोग करती है, जबकि एफएफटी अनिवार्य रूप से पूरी छवि पर एक मतलब है। फ़ंक्शंस भी तेज़ी से कम हो रहे हैं, इसलिए "धुंधली" सीमा निर्धारित करना आसान हो सकता है।
एक ऑटो-फोकस लेंस के साथ कुछ काम के दौरान, मुझे छवि फोकस का पता लगाने के लिए एल्गोरिदम का यह बहुत उपयोगी सेट आया । यह 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;
}
इस बात की कोई गारंटी नहीं है कि ये उपाय आपकी समस्या के लिए सबसे अच्छा विकल्प हैं या नहीं, लेकिन यदि आप इन उपायों से जुड़े कागजात को ट्रैक करते हैं, तो वे आपको अधिक जानकारी दे सकते हैं। आशा है कि आपको कोड उपयोगी लगेगा! मुझे पता है मैंने किया।
नाइके के उत्तर का निर्माण। लैपलैसियन आधारित विधि को ओपनकेव के साथ लागू करने के लिए इसका सीधा:
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;
}
पता चला है कि वास्तविक दुनिया के नमूनों पर मेरे परीक्षणों के आधार पर पता चला है कि एक कैमरा फोकस में है या नहीं, का एक अच्छा संकेत है, जो एक छोटा संकेत है। आश्चर्य की बात नहीं है, सामान्य मूल्य दृश्य निर्भर हैं, लेकिन एफएफटी विधि की तुलना में बहुत कम है जो मेरे आवेदन में उपयोगी होने के लिए झूठी सकारात्मक दर के उच्च है।
मैं पूरी तरह से अलग समाधान के साथ आया था। मैं हर (एक्स) फ्रेम में सबसे तेज एक खोजने के लिए वीडियो अभी भी तख्ते का विश्लेषण करने की जरूरत है। इस तरह, मैं गति छवियों और / या फ़ोकस छवियों से बाहर का पता लगाऊंगा।
मैं कैनी एज डिटेक्शन का उपयोग कर समाप्त हो गया और मुझे लगभग हर तरह के वीडियो के साथ बहुत अच्छे परिणाम मिले (निक्की की विधि के साथ, मुझे डिजिटल वीएचएस वीडियो और भारी इंटरलेस्ड वीडियो के साथ समस्या थी)।
मैंने मूल छवि पर ब्याज क्षेत्र (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));
}
उस महान लाप्लास सुझाव के लिए धन्यवाद निक्की। 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 से कम नहीं होता है।
एक तरीका है जो मैं वर्तमान में उपयोग कर रहा हूँ छवि में किनारों के प्रसार। इस पेपर को देखें:
@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
धुंधली छवियों को प्राप्त करने के लिए इमेजमैगिक के आदेश का उपयोग करके )।
यदि आप विभिन्न आकारों की छवियों की तुलना करते हैं, तो छवि की चौड़ाई को सामान्य करने के लिए मत भूलना, क्योंकि बड़ी छवियों में व्यापक किनारे होंगे।
अंत में, एक महत्वपूर्ण समस्या कलात्मक धुंधला और अवांछित धब्बा (फोकस मिस, संपीड़न, कैमरे के अधीन विषय के सापेक्ष गति के कारण) के बीच भेद कर रही है, लेकिन यह इस तरह के सरल दृष्टिकोणों से परे है। कलात्मक धुंधला के उदाहरण के लिए, लेनना छवि पर एक नज़र डालें: दर्पण में लेनना का प्रतिबिंब धुँधला है, लेकिन उसका चेहरा पूरी तरह से ध्यान में है। यह लेनना छवि के लिए एक उच्च धुंधला अनुमान में योगदान देता है।
मैंने इस पोस्ट से लाप्लासियन फ़िल्टर पर आधारित समाधान की कोशिश की । इसने मेरी मदद नहीं की। इसलिए, मैंने इस पोस्ट से समाधान की कोशिश की और यह मेरे मामले के लिए अच्छा था (लेकिन धीमा है):
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):
ऊपर दिए गए उत्तर कई बातों को स्पष्ट करते हैं, लेकिन मुझे लगता है कि यह एक वैचारिक अंतर बनाने के लिए उपयोगी है।
क्या होगा यदि आप एक धुंधली छवि का पूरी तरह से ध्यान केंद्रित चित्र लेते हैं?
जब आपके पास कोई संदर्भ हो, तो धुंधला पता लगाने की समस्या केवल अच्छी तरह से सामने आती है । यदि आपको डिज़ाइन करने की आवश्यकता है, उदाहरण के लिए, एक ऑटो-फ़ोकस सिस्टम, तो आप धुंधला होने, या चौरसाई करने के विभिन्न डिग्री के साथ ली गई छवियों के अनुक्रम की तुलना करते हैं, और आप इस सेट के भीतर न्यूनतम धुंधलापन का बिंदु खोजने की कोशिश करते हैं। अन्य शब्दों को आपको ऊपर वर्णित तकनीकों में से एक का उपयोग करके विभिन्न छवियों को पार करने की आवश्यकता है (मूल रूप से - दृष्टिकोण में शोधन के विभिन्न संभावित स्तरों के साथ - उच्चतम उच्च आवृत्ति सामग्री के साथ एक छवि की तलाश में)।
दो तरीकों के मतलाब कोड जो उच्च-माना पत्रिकाओं में प्रकाशित किए गए हैं (छवि प्रसंस्करण पर IEEE लेनदेन) यहाँ उपलब्ध हैं: https://ivulab.asu.edu/software
CPBDM और JNBM एल्गोरिदम की जाँच करें। यदि आप कोड की जांच करते हैं तो इसे पोर्ट किया जाना बहुत मुश्किल नहीं है और संयोग से यह मूल विशेषता के रूप में मार्जिलियानो की विधि पर आधारित है।
मैंने इसे 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(:));
इस क्षेत्र में फोकस गुणवत्ता का पता लगाने के लिए मैं 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];