Görüntü verilerini analiz ederek bir görüntünün bulanık olup olmadığını belirlemenin bir yolu olup olmadığını merak ediyordum.
Görüntü verilerini analiz ederek bir görüntünün bulanık olup olmadığını belirlemenin bir yolu olup olmadığını merak ediyordum.
Yanıtlar:
Evet öyle. Hızlı Fourier Dönüşümünü hesaplayın ve sonucu analiz edin. Fourier dönüşümü, görüntüde hangi frekansların bulunduğunu gösterir. Düşük miktarda yüksek frekans varsa, görüntü bulanıklaşır.
'Düşük' ve 'yüksek' terimlerini tanımlamak size bağlıdır.
Düzenle :
Yorumlarda belirtildiği gibi, belirli bir görüntünün bulanıklığını temsil eden tek bir şamandıra istiyorsanız, uygun bir metrik oluşturmanız gerekir.
nikie'nin cevabı böyle bir metrik sağlıyor. Görüntüyü Laplacian çekirdeğiyle birleştirin:
1
1 -4 1
1
Eşikleme için kullanabileceğiniz bir sayı almak için çıktıda sağlam bir maksimum metrik kullanın. Laplacian'ı hesaplamadan önce görüntüleri çok fazla düzeltmekten kaçının, çünkü yalnızca düzgün bir görüntünün gerçekten bulanık olduğunu öğreneceksiniz :-).
Bir görüntünün netliğini tahmin etmenin bir diğer çok basit yolu, bir Laplace (veya LoG) filtresi kullanmak ve sadece maksimum değeri seçmektir. Gürültü bekliyorsanız% 99,9 kantil gibi sağlam bir ölçü kullanmak muhtemelen daha iyidir (örneğin, en yüksek kontrast yerine N'inci en yüksek kontrastı seçmek.) Değişen görüntü parlaklığı bekliyorsanız, görüntü parlaklığını normalleştirmek / kontrast (örn. histogram eşitleme).
Simon'un önerisini ve bunu Mathematica'da uyguladım ve birkaç test görüntüsünde denedim:
İlk test, değişen çekirdek boyutuna sahip bir Gauss filtresi kullanarak test görüntülerini bulanıklaştırır, daha sonra bulanık görüntünün FFT'sini hesaplar ve% 90 en yüksek frekansların ortalamasını alır:
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}]
Logaritmik bir arsa sonucu:
5 çizgi 5 test görüntüsünü, X ekseni Gauss filtre yarıçapını temsil eder. Grafikler azalıyor, bu nedenle FFT keskinlik için iyi bir ölçüdür.
Bu, "en yüksek LoG" bulanıklığı tahmin edicisinin kodudur: Yalnızca bir LoG filtresi uygular ve filtre sonucundaki en parlak pikseli döndürür:
testLaplacian[img_] := Table[
(
blurred = GaussianFilter[img, r];
Max[Flatten[ImageData[LaplacianGaussianFilter[blurred, 1]]]];
), {r, 0, 10, 0.5}]
Logaritmik bir arsa sonucu:
Bulanık olmayan görüntüler için yayılma burada biraz daha iyidir (2.5'e karşı 3.3), çünkü bu yöntem sadece görüntüdeki en güçlü kontrastı kullanırken, FFT aslında tüm görüntü üzerinde bir ortalamadır. İşlevler de daha hızlı azalıyor, bu nedenle "bulanık" bir eşik ayarlamak daha kolay olabilir.
Otomatik odaklama lensiyle yapılan bazı çalışmalar sırasında, görüntü odağını algılamak için bu çok kullanışlı algoritmalarla karşılaştım . MATLAB'da uygulanmıştır, ancak işlevlerin çoğu filter2D ile OpenCV'ye taşınması oldukça kolaydır .
Temelde birçok odak ölçüm algoritmasının bir anket uygulamasıdır. Orijinal makaleleri okumak istiyorsanız, kodda algoritma yazarlarına referanslar verilmiştir. Pertuz ve ark. Odak ölçü operatörlerinin odaktan şekil (SFF) analizi, tüm bu önlemlerin yanı sıra performanslarının (SFF'ye uygulanan hız ve doğruluk açısından) büyük bir incelemesini verir.
EDIT: Bağlantının ölmesi durumunda MATLAB kodu eklendi.
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 sürümlerine birkaç örnek:
// 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;
}
Bu önlemlerin probleminiz için en iyi seçim olup olmadığı konusunda hiçbir garanti yoktur, ancak bu önlemlerle ilişkili kağıtları takip ederseniz size daha fazla fikir verebilirler. Kodu faydalı bulacağınızı umuyoruz! Yaptığımı biliyorum.
Nike'ın cevabından yola çıkarak. Laplacian tabanlı yöntemi opencv ile uygulamak basittir:
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;
}
Gerçek dünya örnekleri üzerindeki testlerime dayanarak algılanan maksimum netliği gösteren kısa bir geri dönecek, bir kameranın odakta olup olmadığını gösteren oldukça iyi bir göstergedir. Şaşırtıcı olmayan bir şekilde, normal değerler sahneye bağımlıdır, ancak uygulamamda yararlı olması için yanlış pozitif oranı yüksek olan FFT yönteminden çok daha azdır.
Tamamen farklı bir çözüm buldum. Her (X) karede en keskin olanı bulmak için video hareketsiz kareleri analiz etmem gerekiyordu. Bu şekilde, hareket bulanıklığını ve / veya odak dışı görüntüleri tespit ederdim.
Canny Edge algılama kullanarak sona erdi ve hemen hemen her tür video ile ÇOK ÇOK iyi sonuçlar aldım (nikie yöntemi ile, dijitalleştirilmiş VHS video ve ağır geçmeli videolar ile sorunları vardı).
Orijinal görüntüde bir ilgi alanı (ROI) ayarlayarak performansı optimize ettim.
EmguCV kullanma:
//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));
}
Bu harika Laplace önerisi için teşekkürler nikie. OpenCV belgeleri bana aynı yöne işaret etti: python, cv2 (opencv 2.4.10) ve numpy kullanarak ...
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
numpy.max(cv2.convertScaleAbs(cv2.Laplacian(gray_image,3)))
sonuç 0-255 arasındadır. 200'ün üzerinde bir şeyin çok odaklandığını gördüm ve 100'e kadar belirgin bir şekilde bulanık. tamamen bulanık olsa bile max asla 20'nin altında olmaz.
Şu anda kullandığım bir yol, görüntüdeki kenarların yayılmasını ölçer. Şu makaleye bakın:
@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} }
Genellikle bir ödeme duvarının arkasında ama bazı ücretsiz kopyalar gördüm. Temel olarak, bir görüntüdeki dikey kenarları bulurlar ve daha sonra bu kenarların ne kadar geniş olduğunu ölçerler. Genişliğin ortalaması, görüntü için son bulanıklaştırma tahmini sonucunu verir. Daha geniş kenarlar bulanık görüntülere karşılık gelir ve bunun tersi de geçerlidir.
Bu sorun referanssız görüntü kalitesi tahmini alanına aittir . Google Akademik'te ararsanız, birçok yararlı referans alırsınız.
DÜZENLE
İşte nikie'nin gönderisindeki 5 resim için elde edilen bulanıklık tahminlerinin bir grafiği. Daha yüksek değerler daha fazla bulanıklığa karşılık gelir. Sabit boyutlu 11x11 Gauss filtresi kullandım ve standart sapmayı değiştirdim ( convert
bulanık görüntüleri elde etmek için imagemagick komutunu kullanarak ).
Farklı boyutlardaki görüntüleri karşılaştırırsanız, daha büyük görüntüler daha geniş kenarlara sahip olacağından görüntü genişliğine göre normalleştirmeyi unutmayın.
Son olarak, önemli bir sorun sanatsal bulanıklığı ve istenmeyen bulanıklığı (odaklama özledim, sıkıştırma, öznenin kameraya göreli hareketinden kaynaklanan) ayırmaktır, ancak bu böyle basit yaklaşımların ötesindedir. Sanatsal bulanıklığın bir örneği için, Lenna görüntüsüne bir göz atın: Lenna'nın aynadaki yansıması bulanık, ancak yüzü mükemmel bir şekilde odaklanmıştır. Bu, Lenna görüntüsü için daha yüksek bir bulanıklık tahminine katkıda bulunur.
Ben gelen Laplace filtresine dayanarak çözüm çalıştı bu yazı. Bana yardımcı olmadı. Yani, gelen çözüm çalıştı bu yazı ve benim durum için iyiydi (ama yavaş):
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))
Daha az bulanık görüntü maksimum sum
değere sahiptir!
Hızı ve doğruluğu, adımı değiştirerek de ayarlayabilirsiniz;
bu kısım
for x in range(width - 1):
bununla değiştirebilirsiniz
for x in range(0, width - 1, 10):
Yukarıdaki yanıtlar birçok şeyi açıkladı, ancak bence kavramsal bir ayrım yapmanın faydalı olduğunu düşünüyorum.
Ya bulanık bir görüntünün mükemmel odaklanmış bir fotoğrafını çekerseniz?
Bulanıklaştırma algılama sorunu yalnızca referansınız olduğunda iyi bir şekilde ortaya çıkar . Örneğin, bir otomatik odaklama sistemi tasarlamanız gerekiyorsa, farklı bulanıklaştırma veya yumuşatma dereceleriyle çekilen bir görüntü dizisini karşılaştırırsınız ve bu sette minimum bulanıklaştırma noktasını bulmaya çalışırsınız. Başka bir deyişle, yukarıda gösterilen tekniklerden birini kullanarak çeşitli görüntüleri çapraz referans almanız gerekir (temel olarak - yaklaşımda çeşitli olası iyileştirme seviyeleriyle - en yüksek yüksek frekans içeriğine sahip bir görüntü aranır).
Yüksek saygın dergilerde (Görüntü İşleme Üzerine IEEE İşlemleri) yayınlanan iki yöntemin Matlab koduna buradan ulaşabilirsiniz: https://ivulab.asu.edu/software
CPBDM ve JNBM algoritmalarını kontrol edin. Kodu kontrol ederseniz, taşınması çok zor değildir ve bu arada Marzialiano'nun temel özelliği olarak yöntemine dayanır.
i matlab içinde fft kullanın ve fft hesaplama ortalama ve std histogram kontrol edin ama aynı zamanda uyum fonksiyonu yapılabilir
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(:));
Bir bölgede odak kalitesini tespit etmek için Opencv'de yaptığım şey bu:
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];