Tôi đã tự hỏi liệu có cách nào để xác định xem một hình ảnh có bị mờ hay không bằng cách phân tích dữ liệu hình ảnh.
Tôi đã tự hỏi liệu có cách nào để xác định xem một hình ảnh có bị mờ hay không bằng cách phân tích dữ liệu hình ảnh.
Câu trả lời:
Vâng, đúng vậy. Tính toán Biến đổi Fourier nhanh và phân tích kết quả. Biến đổi Fourier cho bạn biết tần số nào có trong hình ảnh. Nếu có một lượng tần số cao thấp, thì hình ảnh bị mờ.
Xác định các thuật ngữ 'thấp' và 'cao' là tùy thuộc vào bạn.
Chỉnh sửa :
Như đã nêu trong các ý kiến, nếu bạn muốn một hình nổi duy nhất thể hiện độ mờ của một hình ảnh nhất định, bạn phải tìm ra một số liệu phù hợp.
câu trả lời của nikie cung cấp một số liệu như vậy. Truyền hình ảnh với nhân Laplacian:
1
1 -4 1
1
Và sử dụng một số liệu tối đa mạnh mẽ trên đầu ra để có được một số mà bạn có thể sử dụng để ngưỡng. Cố gắng tránh làm mịn quá nhiều hình ảnh trước khi tính toán Laplacian, bởi vì bạn sẽ chỉ phát hiện ra rằng một hình ảnh được làm mịn thực sự bị mờ :-).
Một cách rất đơn giản khác để ước tính độ sắc nét của hình ảnh là sử dụng bộ lọc Laplace (hoặc LoG) và chỉ cần chọn giá trị tối đa. Sử dụng một biện pháp mạnh như lượng tử 99,9% có lẽ tốt hơn nếu bạn mong đợi nhiễu (tức là chọn độ tương phản cao nhất Nth thay vì độ tương phản cao nhất.) Nếu bạn mong đợi độ sáng hình ảnh thay đổi, bạn cũng nên bao gồm một bước tiền xử lý để bình thường hóa độ sáng hình ảnh / độ tương phản (ví dụ cân bằng biểu đồ).
Tôi đã thực hiện đề xuất của Simon và đề xuất này trong Mathematica và đã thử nó trên một vài hình ảnh thử nghiệm:
Thử nghiệm đầu tiên làm mờ các hình ảnh thử nghiệm bằng bộ lọc Gaussian với kích thước hạt nhân khác nhau, sau đó tính toán FFT của hình ảnh bị mờ và lấy trung bình của tần số cao nhất 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}]
Kết quả trong một lôgarit:
5 dòng đại diện cho 5 hình ảnh thử nghiệm, trục X đại diện cho bán kính bộ lọc Gaussian. Các biểu đồ đang giảm, vì vậy FFT là một thước đo tốt cho độ sắc nét.
Đây là mã cho công cụ ước tính độ mờ "LoG cao nhất": Nó chỉ đơn giản áp dụng bộ lọc LoG và trả về pixel sáng nhất trong kết quả bộ lọc:
testLaplacian[img_] := Table[
(
blurred = GaussianFilter[img, r];
Max[Flatten[ImageData[LaplacianGaussianFilter[blurred, 1]]]];
), {r, 0, 10, 0.5}]
Kết quả trong một lôgarit:
Sự lan truyền cho các hình ảnh không bị mờ ở đây tốt hơn một chút (2,5 so với 3,3), chủ yếu là do phương pháp này chỉ sử dụng độ tương phản mạnh nhất trong ảnh, trong khi FFT về cơ bản là trung bình trên toàn bộ hình ảnh. Các chức năng cũng đang giảm nhanh hơn, do đó có thể dễ dàng hơn để đặt ngưỡng "mờ".
Trong một số công việc với ống kính lấy nét tự động, tôi đã bắt gặp bộ thuật toán rất hữu ích này để phát hiện tiêu cự hình ảnh . Nó được triển khai trong MATLAB, nhưng hầu hết các chức năng khá dễ dàng chuyển sang OpenCV với bộ lọc2D .
Về cơ bản, đây là một triển khai khảo sát của nhiều thuật toán đo trọng tâm. Nếu bạn muốn đọc các bài báo gốc, các tham chiếu đến các tác giả của các thuật toán được cung cấp trong mã. Bài báo năm 2012 của Pertuz, et al. Phân tích các toán tử đo trọng tâm cho hình dạng từ tiêu điểm (SFF) đưa ra đánh giá tuyệt vời về tất cả các biện pháp này cũng như hiệu suất của chúng (cả về tốc độ và độ chính xác khi áp dụng cho SFF).
EDIT: Đã thêm mã MATLAB trong trường hợp liên kết bị chết.
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
%******************************************************************
Một vài ví dụ về các phiên bản 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;
}
Không đảm bảo về việc các biện pháp này có phải là lựa chọn tốt nhất cho vấn đề của bạn hay không, nhưng nếu bạn theo dõi các giấy tờ liên quan đến các biện pháp này, chúng có thể giúp bạn hiểu rõ hơn. Hy vọng bạn tìm thấy mã hữu ích! Tôi biết tôi làm được.
Xây dựng câu trả lời của Nike. Thật đơn giản để thực hiện phương pháp dựa trên laplacian với 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;
}
Sẽ trả về một khoảng ngắn cho biết độ sắc nét tối đa được phát hiện, dựa trên các thử nghiệm của tôi trên các mẫu trong thế giới thực, là một chỉ báo khá tốt về việc máy ảnh có nằm trong tiêu cự hay không. Không ngạc nhiên, giá trị bình thường là cảnh phụ thuộc nhưng nhiều ít hơn so với phương pháp FFT trong đó có đến cao của một tỷ lệ dương tính giả là hữu ích trong ứng dụng của tôi.
Tôi đã đưa ra một giải pháp hoàn toàn khác. Tôi cần phân tích các khung hình video tĩnh để tìm khung hình sắc nét nhất trong mọi khung hình (X). Bằng cách này, tôi sẽ phát hiện mờ chuyển động và / hoặc ra khỏi hình ảnh lấy nét.
Tôi đã kết thúc bằng cách sử dụng phát hiện Canny Edge và tôi đã nhận được RẤT RẤT kết quả tốt với hầu hết mọi loại video (với phương pháp của nikie, tôi gặp vấn đề với video VHS được số hóa và video nặng xen kẽ).
Tôi đã tối ưu hóa hiệu suất bằng cách đặt vùng quan tâm (ROI) trên ảnh gốc.
Sử dụng 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));
}
Cảm ơn nikie cho đề nghị Laplace tuyệt vời đó. Các tài liệu OpenCV đã chỉ cho tôi theo cùng một hướng: sử dụng python, cv2 (opencv 2.4.10) và numpy ...
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
numpy.max(cv2.convertScaleAbs(cv2.Laplacian(gray_image,3)))
kết quả là từ 0-255. Tôi thấy bất cứ thứ gì trên 200ish đều rất tập trung và đến năm 100, nó mờ đi rõ rệt. tối đa không bao giờ thực sự nhận được nhiều dưới 20 ngay cả khi nó hoàn toàn bị mờ.
Một cách mà tôi hiện đang sử dụng là đo độ lan rộng của các cạnh trong ảnh. Hãy tìm bài báo này:
@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} }
Nó thường đứng sau một tường thành nhưng tôi đã thấy một số bản sao miễn phí xung quanh. Về cơ bản, họ định vị các cạnh dọc trong một hình ảnh, và sau đó đo các cạnh đó rộng bao nhiêu. Tính trung bình chiều rộng cho kết quả ước tính mờ cuối cùng cho hình ảnh. Các cạnh rộng hơn tương ứng với hình ảnh mờ và ngược lại.
Vấn đề này thuộc về lĩnh vực ước tính chất lượng hình ảnh không tham chiếu . Nếu bạn tra cứu nó trên Google Scholar, bạn sẽ nhận được nhiều tài liệu tham khảo hữu ích.
BIÊN TẬP
Đây là một âm mưu của các ước tính mờ thu được cho 5 hình ảnh trong bài đăng của nikie. Giá trị cao hơn tương ứng với độ mờ lớn hơn. Tôi đã sử dụng bộ lọc Gaussian 11x11 kích thước cố định và thay đổi độ lệch chuẩn (sử dụng convert
lệnh của fantemagick để thu được các hình ảnh mờ).
Nếu bạn so sánh hình ảnh có kích thước khác nhau, đừng quên bình thường hóa theo chiều rộng hình ảnh, vì hình ảnh lớn hơn sẽ có các cạnh rộng hơn.
Cuối cùng, một vấn đề quan trọng là phân biệt giữa mờ nghệ thuật và mờ không mong muốn (gây ra bởi lỗi lấy nét, nén, chuyển động tương đối của đối tượng với máy ảnh), nhưng đó là cách tiếp cận đơn giản như cách này. Để có một ví dụ về mờ nghệ thuật, hãy nhìn vào hình ảnh Lenna: Hình ảnh phản chiếu của Lenna trong gương bị mờ, nhưng khuôn mặt của cô ấy hoàn toàn tập trung. Điều này góp phần ước tính độ mờ cao hơn cho hình ảnh Lenna.
Tôi đã thử giải pháp dựa trên bộ lọc Laplacian từ bài đăng này . Nó không giúp tôi. Vì vậy, tôi đã thử giải pháp từ bài đăng này và nó tốt cho trường hợp của tôi (nhưng chậm):
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))
Hình ảnh mờ ít hơn có sum
giá trị tối đa !
Bạn cũng có thể điều chỉnh tốc độ và độ chính xác bằng cách thay đổi bước, ví dụ:
phần này
for x in range(width - 1):
bạn có thể thay thế bằng cái này
for x in range(0, width - 1, 10):
Câu trả lời ở trên đã làm sáng tỏ nhiều điều, nhưng tôi nghĩ nó rất hữu ích để tạo ra sự khác biệt về khái niệm.
Điều gì nếu bạn chụp một bức ảnh hoàn toàn tập trung vào một hình ảnh mờ?
Vấn đề phát hiện mờ chỉ được đặt ra khi bạn có một tài liệu tham khảo . Nếu bạn cần thiết kế, ví dụ: hệ thống lấy nét tự động, bạn so sánh một chuỗi hình ảnh được chụp với các mức độ làm mờ hoặc làm mịn khác nhau và bạn cố gắng tìm điểm mờ tối thiểu trong bộ này. Nói cách khác, bạn cần tham chiếu chéo các hình ảnh khác nhau bằng một trong những kỹ thuật được minh họa ở trên (về cơ bản - với nhiều mức độ tinh chỉnh khác nhau trong cách tiếp cận - tìm kiếm một hình ảnh có nội dung tần số cao nhất).
Mã Matlab của hai phương pháp đã được xuất bản trên các tạp chí được đánh giá cao (Giao dịch của IEEE về Xử lý hình ảnh) có sẵn tại đây: https://ivulab.asu.edu/software
kiểm tra các thuật toán CPBDM và JNBM. Nếu bạn kiểm tra mã, sẽ không khó để chuyển và tình cờ nó dựa trên phương pháp của Marzialiano như là tính năng cơ bản.
tôi đã thực hiện nó sử dụng fft trong matlab và kiểm tra biểu đồ của trung bình tính toán fft và std nhưng cũng có thể thực hiện chức năng phù hợp
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(:));
Đó là những gì tôi làm trong Opencv để phát hiện chất lượng tập trung trong một khu vực:
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];