Bài toán: cần làm nổi rõ những bất thường trên ảnh. Điểm bất thường có thể là những dị biệt trong ảnh đầu vào chẳng hạn như vết đọng đá vôi trong mắt, hoặc vết rớt mực trong bản chữ viết tay.
Dữ liệu vào: ảnh I1có định dạng *.png, *.jpg hay *.bmp, là ảnh màu hoặc ảnh xám.
Dữ liệu ra: ảnh kết quả cùng kích thước và định dạng với ảnh nguồn. Thuật toán: Được mô tả qua danh sách các bước như sau:
1. Đọc ảnh nguồn I1.
2. Tìm I2 là thành phần ảnh Green của I1
3. Tính I3 là kết quả của phép hình thái imbothat với I2
4. Tính I4 là kết quả của phép hình thái imtophat với I3
5. Bổ sung đường viền contour vào ảnh kết quả I3-I2
Giao diện của chương trình được cho trong Hình 3.3. Hiệu quả của phương pháp thể hiện trong thử nghiệm này cho bởi các giá trị MSE là 403.9604 và giá trị PSNR là 22.0674.
Hình 3.3. Làm rõ điểm bất thường 3.5. Kết hợp các phép toán hình thái để khử nhiễu ảnh
Bài toán: Cho trước ảnh đầu vào có nhiều chi tiết thừa, nhiễu. Cần loại bỏ chúng để chỉ giữ những phần chính. Những chi tiết thừa này có thể là vết lem mực, nhòe, ố,…
Dữ liệu vào: ảnh I1có định dạng *.png, *.jpg hay *.bmp, là ảnh màu hoặc ảnh xám.
Dữ liệu ra: ảnh kết quả cùng kích thước và định dạng với ảnh nguồn. Thuật toán: Được mô tả qua danh sách các bước như sau:
1. Đọc ảnh nguồn I1.
2. Tìm I2 là thành phần ảnh Blue của I1
3. Tìm I3 là ảnh làm mịn của I2
Giao diện của chương trình:
Hình 3.4. Khử nhiễu ảnh
Kết quả: giá trị MSE là 5000.0589, giá trị PSNR là 11.1411
Ngoài ra, một số hình ảnh OCR đơn giản cũng được thử nghiệm với ứng dụng này.
Hình b.
Hình c.
Có thể thấy, hình ảnh kết quả thu được đã rõ hơn và bị loại bỏ các nhiễu trong ảnh.
Áp dụng công thức MSE và PSNR ta có kết quả thử nghiệm được thống kê trong bảng sau.
Bảng 3.1 Kết quả thử nghiệm Thử nghiệm MSE PSNR 3.2 8310.4535 8.9346 3.3 403.9604 22.0674 3.4 5000.0589 11.1411 3.5.a 1528.7836 16.2873 3.5.b 2124.3791 14.8585 3.5.c 1340.3215 16.8587
Kết quả thử nghiệm trong bảng 3.1 cho thấy nội dung chính của các ảnh sau khi nâng cao chất lượng ảnh gần như không thay đổi, đặc biệt là các thử nghiệm với ảnh OCR, ngoại trừ những phần tử ảnh nhiễu nhỏ.
Trong số 6 thử nghiệm, thì thử nghiệm 3.2 có kết quả kém nhất, thử nghiệm 3.3 cho kết quả tốt nhất. Ngoài ra, ba kết quả trong các thử nghiệm cuối với ảnh OCR cho kết quả tương đối ổn định với các dữ liệu khác nhau và giá trị PSNR thay đổi không nhiều (sai khác ~2).
KẾT LUẬN Kết quả đã đạt được
-Nghiên cứu tổng quan về xử lý ảnh và phép toán hình thái: Khái niệm xử lý ảnh, quá trình xử lý ảnh và các khái niệm về phép toán hình thái học; Một số tính chất nội suy của phép toán hình thái học: Trên ảnh xám, ảnh màu và nêu ra tính chất nội suy của phép toán hình thái học và các phép lọc hình thái học cho ảnh OCR.
-Xây dựng chương trình thử nghiệm phép lọc hình thái học ứng dụng cho ảnh tài liệu kém chất lượng: cài đặt thử nghiệm phép lọc hình thái và đánh giá MSE.
Hướng phát triển
- Tối ưu các thuật toán để cải thiện tốc độ cũng như chất lượng ảnh. - Căn cứ vào đánh giá MSE và PSNR để điều chỉnh các tham số cho các thuật toán.
TÀI LIỆU THAM KHẢO A. TIẾNG VIỆT
[1]. Nguyễn Xuân Vinh (2010), Phép toán hình thái học, Luận văn khoa học Thạc sỹ công nghệ thông tin, Khoa Công nghệ thông tin – Đại học Thái Nguyên.
B. TIẾNG ANH
[2]. Dr. Pierre Soille(2004), Morphological Image Analysis - Principles and Applications, Springer-Verlag Berlin Heidelberg.
[3]. Laurent Najman, Hugues Talbot (2010), Mathematical Morphology- From Theory to Applications, Wiley-ISTE.
[4].Xaro Benavent, Esther Dura, Francisco Vegara, and Juan Domingo (2012), Mathematical Morphology for Color Images: An Image-Dependent Approach, Mathematical Problems in Engineering, pp. 1-18.
[5].Charles Jacobs, Patrice Y. Simard, Paul Viola, and James Rinker (2005),Text Recognition of Low-resolution Document Images, Eighth International Conference on Document Analysis and Recognition (ICDAR'05), Seoul, South Korea, pp. 695-699.
[6]. Aditya Challa, Sravan Danda, B S Daya Sagar, Laurent Najman (2018), Some Properties of Interpolations Using Mathematical Morphology, IEEE Transactions on Image Processing, vol. 27, no. 4, pp. 2038-2048.
[7]. Dias F., Cousty J., Najman L. (2011), Some Morphological Operators on Simplicial Complex Spaces, Proceedings of the 16th IAPR international conference on Discrete geometry for computer imagery, pp. 441–452.
PHỤ LỤC 1. Một số hàm Matlab dùng trong xử lý ảnh
imerode imerode(I, SE) xóa bỏ thang màu xám, nhị phân hoặc hình ảnh nhị phân đóng gói I, trả lại hình ảnh bị xói mòn. SE là một đối tượng phần tử có cấu trúc hoặc mảng các đối tượng phần tử có cấu trúc, được trả về bởi các hàm strel hoặc offsetstrel.
imdilate imdilate(I, SE) làm giãn màu xám, nhị phân hoặc hình ảnh nhị phân đóng gói I, trả về hình ảnh được làm giãn. SE là đối tượng phần tử có cấu trúc hoặc mảng các đối tượng phần tử có cấu trúc, được trả về bởi các hàm strel hoặc offsetstrel.
imopen imopen(I, SE) thực hiện mở hình thái trên thang độ xám hoặc hình ảnh nhị phân I, trả về hình ảnh đã mở. SE là một đối tượng phần tử có cấu trúc đơn được trả về bởi các hàm strel hoặc offsetstrel. Hoạt động mở hình thái là một sự xói mòn theo sau là một sự giãn nở, sử dụng cùng một phần tử cấu trúc cho cả hai hoạt động.
imclose imclose(I, SE) thực hiện đóng hình thái trên thang màu xám hoặc hình ảnh nhị phân I, trả về hình ảnh đã đóng. SE là một đối tượng phần tử có cấu trúc đơn được trả về bởi các hàm strel hoặc offsetstrel. Hoạt động đóng theo hình thái học là một sự giãn nở theo sau là một sự xói mòn, sử dụng cùng một phần tử cấu trúc cho cả hai hoạt động.
imtophat imtophat(I, SE) thực hiện lọc top-hat hình thái trên thang độ xám hoặc hình ảnh nhị phân I, trả về hình ảnh đã lọc. Top-hat filter tính toán độ mở hình thái của hình ảnh (sử dụng imopen) và sau đó lấy kết quả trừ đi kết quả ban đầu hình ảnh. SE là một đối
tượng phần tử có cấu trúc đơn được trả về bởi các hàm strel hoặc offsetstrel.
imbothat imbothat(I, SE) thực hiện lọc mũ đáy hình thái trên thang độ xám hoặc hình ảnh nhị phân I, trả về hình ảnh đã lọc. Lọc mũ đáy tính toán việc đóng hình thái của hình ảnh (sử dụng imclose) và sau đó trừ hình ảnh gốc khỏi kết quả. SE là một đối tượng phần tử có cấu trúc đơn được trả về bởi các hàm strel hoặc offsetstrel.
immse Immse(X, Y) tính toán sai số trung bình (MSE) giữa mảng X và Y.
2. Mã nguồn
Phần này trình bày các mã nguồn chính xây dựng chương trình thử nghiệm.
* Phép toán hình thái cơ bản
f1=double(imread('lena512.bmp')); f=f1(:,:,1); subplot(2,3,1); imshow(uint8(f)); title('Original image'); [x,y]=size(f); p=zeros(x,y);p2=zeros(x,y);p12=zeros(x,y);p13=zeros( x,y); %Phép toán Dilation w=[1 1 1; 1 1 1; 1 1 1]; for s=2:x-2 for t=2:y-2
w1=[f(s-1,t-1)*w(1) f(s-1,t)*w(2) f(s- 1,t+1)*w(3) f(s,t-1)*w(4) f(s,t)*w(5) f(s,t+1)*w(6) f(s+1,t-1)*w(7) f(s+1,t)*w(8) f(s+1,t+1)*w(9)]; p(s,t)=max(w1); end end subplot(2,3,2); imshow(uint8(p)); title('Dilated image'); %Phép toán Erosion w=[1 1 1; 1 1 1; 1 1 1]; for s=2:x-1 for t=2:y-1 w12=[f(s-1,t-1)*w(1) f(s-1,t)*w(2) f(s- 1,t+1)*w(3) f(s,t-1)*w(4) f(s,t)*w(5) f(s,t+1)*w(6) f(s+1,t-1)*w(7) f(s+1,t)*w(8) f(s+1,t+1)*w(9)]; p1(s,t)=min(w12); end end subplot(2,3,3); imshow(uint8(p1)); title('Eroded image'); %Phép toán Opening [m,n]=size(p); w=[1 1 1; 1 1 1; 1 1 1]; for s=2:m-1 for t=2:n-1
w13=[p(s-1,t-1)*w(1) p(s-1,t)*w(2) p(s- 1,t+1)*w(3) p(s,t-1)*w(4) p(s,t)*w(5) p(s,t+1)*w(6) p(s+1,t-1)*w(7) p(s+1,t)*w(8) p(s+1,t+1)*w(9)]; p12(s,t)=min(w13); end end subplot(2,3,4); imshow(uint8(p12)); title('opening of image'); %Phép toán Closing [r,c]=size(p1); w=[1 1 1; 1 1 1; 1 1 1]; for s=2:r-1 for t=2:c-1 w14=[p1(s-1,t-1)*w(1) p1(s-1,t)*w(2) p1(s- 1,t+1)*w(3) p1(s,t-1)*w(4) p1(s,t)*w(5) p1(s,t+1)*w(6) p1(s+1,t-1)*w(7) p1(s+1,t)*w(8) p1(s+1,t+1)*w(9)]; p13(s,t)=min(w14); end end subplot(2,3,5); imshow(uint8(p13)); title('Closing of image');
* Loại bỏ nhiễu để làm rõ đối tượng
axes(handles.axes2); se = strel('disk',15);
background = imopen(I,se);%I là ảnh gốc I2 = I - background;
I3 = imadjust(rgb2gray(I2)); bw = imbinarize(I3); bw = bwareaopen(bw,50); imshow(imlocalbrighten(double(bw),0.6)); F = getframe(handles.axes2); Image2 = frame2im(F); err = immse(Image1,Image2);
str1= sprintf('The MSE is %0.4f', err); str2= sprintf('The PSNR is %0.4f', 10*log10(255*255/err)); str3=sprintf('%s. %s',str1,str2); handles.edit1.String = str3; * Làm rõ điểm bất thường R=I(:,:,1); G=I(:,:,2); B=I(:,:,3); se=strel('disk',5); C=imbothat(G,se); %lọc hình thái se=strel('disk',8); H=imtophat(G,se);%lọc hình thái tmp=im2bw(H-C,.2); imshow(I);hold on; F = getframe(handles.axes2); Image1 = frame2im(F); u=contour(tmp,'b'); F = getframe(handles.axes2); Image2 = frame2im(F); err = immse(Image1,Image2);
str2= sprintf('The PSNR is %0.4f', 10*log10(255*255/err));
str3=sprintf('%s. %s',str1,str2); handles.edit1.String = str3;
* Kết hợp các phép toán hình thái để khử nhiễu ảnh
function J = bwsmooth( I, params ) params = parameter_set( params ); D = bw2dist( I, params );
D = smooth_dist( D, params ); J = dist2bw( D, params ); end
function params = parameter_set( params_ ) params.bz_thresh = 0;
params.as_scale = 1;
names = fieldnames( params_ ); for i = 1:length( names )
name = names{ i };
params = setfield( params, name, getfield( params_, name ) );
end end
function D = bw2dist( B, params ) B_posi = B > 0; % char
B_nega = ~B_posi; % bg
D = bwdist( bwperim( B_posi ), 'quasi-euclidean' ); D_posi = B_posi .* D;
D_nega = -(B_nega .* D); D = D_posi + D_nega; end
function D_ = smooth_dist( D, params ) nite = 30; % number of iterations
wsize = 5; % window size of gaussian function wsigma = 1.5; % standard deviation
enhance = 20; % enchancement degree. (enhance > 0) dt = 0.25; % time step
scale = params.as_scale;
D_ = imresize( D, scale, 'cubic' );
D_= impdevec(D_, wsize, wsigma, enhance, dt, nite); D_ = imresize( D_, size(D), 'cubic' );
if params.debug
figure(1001), imshow( 1./ (1 + exp(-0.1*[D, D_]))); title( 'Smoothing for a distance image. before
(left) and after (right)' ); DD = [D, D_];
DD( DD>0 ) = 0; DD = -DD;
DD = exp( -DD/ 5 );
figure(1002), imagesc( DD ); axis image;
title( 'before / after with color enhancement for displaying');
end end
function B = dist2bw( D, params ) thresh = params.bz_thresh;
B = D > thresh; end
[sy, sx, sc] = size(I); J = I; Hx = 0.5 * [ -1, 0, 1 ]; Hy = Hx'; Hxx = [ 1 -2 1 ]; Hyy = Hxx'; Hxy = 0.25 * [ 1 0 -1; 0 0 0; -1 0 1 ]; K = fspecial( 'gaussian', wsize, wsigma ); for iItr = 1:nIter
[Ix, Iy] = gradient_( J, Hx, Hy );
[G11, G12, G21, G22] = structure_tensor( Ix, Iy, K );
[R_min, R_max, Vx, Vy] = gradv( G11, G12, G21, G22 ); r_std = enhance / ( std( sqrt( R_min( : ) ) ) + eps(1) ); R_min = r_std * R_min; R_max = r_std * R_max; R2 = 1 ./ ( 1 + R_min + R_max ); R1 = sqrt( R2 ); [D11, D12, D21, D22] = diffusion_tensor( R1, R2, Vx, Vy, sc );
[Ixx, Ixy, Iyx, Iyy ] = hessian_( J, Hxx, Hxy, Hyy );
DH = ( D11 .* Ixx + D12 .* Ixy ) + ( D21 .* Iyx + D22 .* Iyy );
J = J + dt * DH; end
function [Ix, Iy] = gradient_( I, Hx, Hy ) Ix = imfilter( I, Hx, 'replicate' ); Iy = imfilter( I, Hy, 'replicate' ); end
function [ Ixx, Ixy, Iyx, Iyy ] = hessian_( I, Hxx, Hxy, Hyy )
Ixx = imfilter( I, Hxx, 'replicate' ); Ixy = imfilter( I, Hxy, 'replicate' ); Iyx = Ixy;
Iyy = imfilter( I, Hyy, 'replicate' ); end function [G11, G12, G21, G22] = structure_tensor( Ix, Iy, K ) G11 = sum( Ix.*Ix, 3 ); G12 = sum( Ix.*Iy, 3 ); G22 = sum( Iy.*Iy, 3 ); G11 = imfilter( G11, K, 'replicate' ); G12 = imfilter( G12, K, 'replicate' ); G21 = G12; G22 = imfilter( G22, K, 'replicate' ); end function [ D11, D12, D21, D22 ] = diffusion_tensor( R1, R2, Vx, Vy, sc ) D11 = R2 .* Vx.*Vx + R1 .* Vy.*Vy; D12 = R2 .* Vx.*Vy - R1 .* Vy.*Vx; D22 = R2 .* Vy.*Vy + R1 .* Vx.*Vx; D11 = repmat( D11, [ 1 1 sc ] ); D12 = repmat( D12, [ 1 1 sc ] );
D22 = repmat( D22, [ 1 1 sc ] ); end
function [ R_min, R_max, Vx, Vy ]... = gradv( G11, G12, G21, G22 ) a = G11 + G22; b = G11 - G22; c = G12 .* G21; d = sqrt( b.^2 + 4 * c ); R_min = 0.5 * ( a - d ); R_max = 0.5 * ( a + d ); R_min = max( R_min, 0 ); R_max = max( R_max, 0 );
t_max = atan2( R_max - G11, G12 ); Vx = cos( t_max ); Vy = sin( t_max ); end fname = 'exam1.bmp'; I = imread(fname); imshow( I ); B = I > 0; B = B(:,:,1); params.bz_thresh = -0; params.as_scale = 1/4;
params.debug = 1; % show all figures B_our = bwsmooth(B,params);
figure(1),
imshow( [B, B_our] );
title( 'Original binarized image (Left) and Smoothed image (Right)' );
SE = strel('square',4); figure(3), imshow(B_our); a= imopen(imcomplement(B_our), SE); figure(4), imshow(imcomplement(a)); a=imdilate(a,SE); figure(5), imshow(imcomplement(a)); IM2=I(:,:,[1 1 1]); IM3=a(:,:,[1 1 1]); I2=im2uint8(IM2); I3=im2uint8(IM3); err = immse(I2,I3);
str1= sprintf('The MSE is %0.4f', err); str2= sprintf('The PSNR is %0.4f',
10*log10(255*255/err));
str3=sprintf('%s. %s',str1,str2); handles.edit1.String = str3;