Saya bertanya-tanya apakah ada cara untuk menentukan apakah suatu gambar buram atau tidak dengan menganalisis data gambar.
Saya bertanya-tanya apakah ada cara untuk menentukan apakah suatu gambar buram atau tidak dengan menganalisis data gambar.
Jawaban:
Ya itu. Hitung Fast Fourier Transform dan analisis hasilnya. Transformasi Fourier memberi tahu Anda frekuensi mana yang ada dalam gambar. Jika ada frekuensi rendah dalam jumlah rendah, maka gambarnya buram.
Menentukan istilah 'rendah' dan 'tinggi' terserah Anda.
Edit :
Seperti yang dinyatakan dalam komentar, jika Anda ingin satu float mewakili kekaburan gambar tertentu, Anda harus membuat metrik yang sesuai.
Jawaban nikie memberikan metrik seperti itu. Gabungkan gambar dengan kernel Laplacian:
1
1 -4 1
1
Dan gunakan metrik maksimum yang kuat pada output untuk mendapatkan nomor yang dapat Anda gunakan untuk thresholding. Cobalah untuk menghindari merapikan terlalu banyak gambar sebelum menghitung Laplacian, karena Anda hanya akan menemukan bahwa gambar yang dihaluskan memang buram :-).
Cara lain yang sangat sederhana untuk memperkirakan ketajaman suatu gambar adalah dengan menggunakan filter Laplace (atau LoG) dan cukup memilih nilai maksimum. Menggunakan ukuran yang kuat seperti 99,9% kuantil mungkin lebih baik jika Anda mengharapkan noise (yaitu memilih kontras ke-N tertinggi daripada kontras tertinggi.) Jika Anda mengharapkan berbagai kecerahan gambar, Anda juga harus memasukkan langkah preprocessing untuk menormalkan kecerahan gambar / kontras (mis. pemerataan histogram).
Saya telah mengimplementasikan saran Simon dan yang ini di Mathematica, dan mencobanya pada beberapa gambar uji:
Tes pertama mengaburkan gambar uji menggunakan filter Gaussian dengan ukuran kernel yang bervariasi, kemudian menghitung FFT dari gambar buram dan mengambil rata-rata frekuensi tertinggi 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}]
Menghasilkan plot logaritmik:
5 garis mewakili 5 gambar uji, sumbu X mewakili jari-jari filter Gaussian. Grafik menurun, sehingga FFT adalah ukuran yang baik untuk ketajaman.
Ini adalah kode untuk penaksir keburaman "LoG tertinggi": Ini hanya menerapkan filter LoG dan mengembalikan piksel paling terang dalam hasil filter:
testLaplacian[img_] := Table[
(
blurred = GaussianFilter[img, r];
Max[Flatten[ImageData[LaplacianGaussianFilter[blurred, 1]]]];
), {r, 0, 10, 0.5}]
Menghasilkan plot logaritmik:
Penyebaran untuk gambar yang tidak kabur sedikit lebih baik di sini (2,5 vs 3,3), terutama karena metode ini hanya menggunakan kontras terkuat dalam gambar, sedangkan FFT pada dasarnya adalah rata-rata di seluruh gambar. Fungsi-fungsinya juga menurun lebih cepat, jadi mungkin lebih mudah untuk menetapkan ambang batas "buram".
Selama beberapa pekerjaan dengan lensa fokus otomatis, saya menemukan serangkaian algoritma yang sangat berguna ini untuk mendeteksi fokus gambar . Ini diimplementasikan dalam MATLAB, tetapi sebagian besar fungsi cukup mudah untuk port ke OpenCV dengan filter2D .
Ini pada dasarnya merupakan implementasi survei dari banyak algoritma pengukuran fokus. Jika Anda ingin membaca makalah asli, referensi ke penulis algoritma disediakan dalam kode. Makalah 2012 oleh Pertuz, et al. Analisis operator ukuran fokus untuk bentuk dari fokus (SFF) memberikan ulasan yang baik dari semua ukuran ini serta kinerja mereka (baik dalam hal kecepatan dan akurasi seperti yang diterapkan pada SFF).
EDIT: Menambahkan kode MATLAB untuk berjaga-jaga jika tautannya mati.
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
%******************************************************************
Beberapa contoh versi 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;
}
Tidak ada jaminan apakah langkah-langkah ini adalah pilihan terbaik untuk masalah Anda, tetapi jika Anda melacak makalah yang terkait dengan tindakan ini, mereka mungkin memberi Anda wawasan lebih lanjut. Semoga kode ini bermanfaat! Saya tahu saya melakukannya.
Membangun dari jawaban Nike. Sangat mudah untuk mengimplementasikan metode berbasis laplacian dengan 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;
}
Akan menampilkan pendek yang menunjukkan ketajaman maksimum yang terdeteksi, yang didasarkan pada pengujian saya pada sampel dunia nyata, merupakan indikator yang cukup baik jika kamera fokus atau tidak. Tidak mengherankan, nilai normal tergantung pada adegan tetapi jauh lebih sedikit daripada metode FFT yang memiliki tingkat positif palsu yang tinggi untuk berguna dalam aplikasi saya.
Saya datang dengan solusi yang sama sekali berbeda. Saya perlu menganalisis frame video untuk menemukan yang paling tajam di setiap frame (X). Dengan cara ini, saya akan mendeteksi gambar blur dan / atau tidak fokus.
Saya akhirnya menggunakan deteksi Canny Edge dan saya mendapatkan hasil yang SANGAT SANGAT bagus dengan hampir setiap jenis video (dengan metode nikie, saya memiliki masalah dengan video VHS digital dan video interlaced berat).
Saya mengoptimalkan kinerja dengan menetapkan wilayah minat (ROI) pada gambar asli.
Menggunakan 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));
}
Terima kasih nikie untuk saran Laplace yang hebat itu. OpenCV docs menunjuk saya ke arah yang sama: menggunakan python, cv2 (opencv 2.4.10), dan numpy ...
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
numpy.max(cv2.convertScaleAbs(cv2.Laplacian(gray_image,3)))
hasilnya adalah antara 0-255. Saya menemukan sesuatu yang berusia lebih dari 200 tahun sangat fokus, dan pada usia 100, terlihat buram. maks tidak pernah benar-benar mendapat jauh di bawah 20 bahkan jika itu benar-benar kabur.
Salah satu cara yang saya gunakan saat ini adalah mengukur penyebaran tepi pada gambar. Cari makalah ini:
@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} }
Biasanya di balik paywall tetapi saya telah melihat beberapa salinan gratis di sekitar. Pada dasarnya, mereka menemukan tepi vertikal dalam gambar, dan kemudian mengukur seberapa lebar tepi tersebut. Rata-rata lebar memberikan hasil estimasi blur akhir untuk gambar. Tepi yang lebih luas berhubungan dengan gambar buram, dan sebaliknya.
Masalah ini milik bidang estimasi kualitas gambar tanpa referensi . Jika Anda mencarinya di Google Cendekia, Anda akan mendapatkan banyak referensi yang bermanfaat.
EDIT
Berikut plot perkiraan blur yang diperoleh untuk 5 gambar di pos nikie. Nilai yang lebih tinggi sesuai dengan kekaburan yang lebih besar. Saya menggunakan filter Gaussian ukuran 11x11 ukuran tetap dan memvariasikan standar deviasi (menggunakan convert
perintah imagemagick untuk mendapatkan gambar buram).
Jika Anda membandingkan gambar dengan ukuran berbeda, jangan lupa untuk menormalkan dengan lebar gambar, karena gambar yang lebih besar akan memiliki tepi yang lebih lebar.
Akhirnya, masalah yang signifikan adalah membedakan antara blur artistik dan blur yang tidak diinginkan (disebabkan oleh kehilangan fokus, kompresi, gerakan relatif subjek ke kamera), tetapi itu di luar pendekatan sederhana seperti ini. Sebagai contoh kekaburan artistik, lihatlah gambar Lenna: Refleksi Lenna di cermin buram, tetapi wajahnya benar-benar fokus. Ini berkontribusi pada perkiraan blur yang lebih tinggi untuk gambar Lenna.
Saya mencoba solusi berdasarkan filter Laplacian dari posting ini . Itu tidak membantu saya. Jadi, saya mencoba solusi dari posting ini dan itu bagus untuk kasus saya (tetapi lambat):
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))
Gambar yang kurang buram memiliki maksimum sum
nilai !
Anda juga dapat mengatur kecepatan dan akurasi dengan mengubah langkah, misalnya
bagian ini
for x in range(width - 1):
Anda dapat mengganti dengan yang ini
for x in range(0, width - 1, 10):
Jawaban di atas menjelaskan banyak hal, tetapi saya pikir berguna untuk membuat perbedaan konseptual.
Bagaimana jika Anda mengambil gambar yang benar-benar fokus pada gambar yang buram?
Masalah deteksi kabur hanya diajukan dengan baik ketika Anda memiliki referensi . Jika Anda perlu merancang, misalnya, sistem fokus otomatis, Anda membandingkan urutan gambar yang diambil dengan berbagai tingkat kekaburan, atau menghaluskan, dan Anda mencoba menemukan titik kekaburan minimum dalam set ini. Saya kata lain Anda perlu referensi silang berbagai gambar menggunakan salah satu teknik yang diilustrasikan di atas (pada dasarnya - dengan berbagai tingkat penyempurnaan dalam pendekatan - mencari satu gambar dengan konten frekuensi tinggi tertinggi).
Kode Matlab dari dua metode yang telah diterbitkan dalam jurnal yang sangat dihormati (Transaksi IEEE pada Pemrosesan Gambar) tersedia di sini: https://ivulab.asu.edu/software
periksa algoritma CPBDM dan JNBM. Jika Anda memeriksa kode itu tidak terlalu sulit untuk porting dan kebetulan itu didasarkan pada metode Marzialiano sebagai fitur dasar.
saya menerapkannya menggunakan fft di matlab dan memeriksa histogram dari rata-rata menghitung fft dan std tetapi juga fungsi fit dapat dilakukan
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(:));
Itulah yang saya lakukan di Opencv untuk mendeteksi kualitas fokus di suatu wilayah:
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];