You are on page 1of 24

BTVN XỬ LÝ ẢNH

NGUYỄN VIỆT HÙNG


20KTMT1
STT:14

buổi 1:
1) viết chương trình xoay ảnh một góc alpha
CODE:
image = imread('peppers.png');
figure(1), clf, hold on
subplot(1,2,1)
imshow(image);
degree = 45;
switch mod(degree, 360)
case 0
imagerot = image;
case 90
imagerot = rot90(image);
case 180
imagerot = image(end:-1:1, end:-1:1);
case 270
imagerot = rot90(image(end:-1:1, end:-1:1));
otherwise
a = degree*pi/180;
R = [+cos(a) +sin(a); -sin(a) +cos(a)];
[m,n,p] = size(image);
dest = round( [1 1; 1 n; m 1; m n]*R );
dest = bsxfun(@minus, dest, min(dest)) + 1;
imagerot = zeros([max(dest) p],class(image));

for ii = 1:size(imagerot,1)
for jj = 1:size(imagerot,2)
source = ([ii jj]-dest(1,:))*R.';
if all(source >= 1) && all(source <= [m n])
C = ceil(source);
F = floor(source);
A = [...
((C(2)-source(2))*(C(1)-source(1))),...
((source(2)-F(2))*(source(1)-F(1)));
((C(2)-source(2))*(source(1)-F(1))),...
((source(2)-F(2))*(C(1)-source(1)))];
cols = bsxfun(@times, A, double(image(F(1):C(1),F(2):C(2),:)));
imagerot(ii,jj,:) = sum(sum(cols),2);
end
end
end
end

subplot(1,2,2)
imshow(imagerot);

KẾT QUẢ:

2) Viết chương trình tạo ảnh gif


CODE:
% Create a GIF animation image.
clear all
x = 0:0.01:1;
p = plot(nan,nan);
p.XData = x;
for n = 1:0.5:5
p.YData = x.^n;
exportgraphics(gcf,'testAnimated.gif','Append',true);
end
x = 0:0.01:1;
figure(1)
filename = 'testimage.gif';
for n = 1:0.5:5
y = x.^n;
plot(x,y)
drawnow
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if n == 1;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');end
end
imshow(filename)

KẾT QUẢ:

---------------------------------------------------------------------------------------------
Buổi 2: chia 1 ảnh thành 16 phần rồi xáo trộn

CODE:

idx = randperm(num_rows * num_cols);


C_shuffle = C(idx);
img_new = cell2mat(reshape(C_shuffle, [num_rows, num_cols]));
figure;
subplot(1, 2, 1);
imshow(img);
title('Ảnh gốc');
subplot(1, 2, 2);
imshow(img_new);
title('Ảnh sau khi xáo trộn');
KẾT QUẢ

---------------------------------------------------------------------------------------------
Buổi 3:
1) tìm và vẽ histogram của ảnh xám bất kỳ.
2) cân bằng histogram đó và nhận xét so sánh vs hàm có sẵn

CODE:
clc
clear all
close all
warning off
x= imread('http://nghiencuuquocte.org/wp-
content/uploads/2018/03/14.jpg');
subplot(3,2,1);
imshow(x);
title('Original Image');
subplot(3,2,2);
imhist(x);
title('Histogram of Original Image using built in function');
axis tight;
h=zeros(1,256);
[r c]=size(x);
totla_no_of_pixels=r*c;
n=0:255;
j=histeq(x);
subplot(3,2,3);imshow(j);
title('Histogram Equalization using built in function');
subplot(3,2,4);
imhist(j);
axis tight;
title('Histogram Equalization using built in function');for i=1:r
for j=1:c
h(x(i,j)+1)=h(x(i,j)+1)+1;

end
end
for i=1:256
h(i)=h(i)/totla_no_of_pixels;
end
temp=h(1);
for i=2:256
temp=temp+h(i);
h(i)=temp;
end

for i=1:r
for j=1:c
x(i,j)=round(h(x(i,j)+1)*255);
end
end
subplot(3,2,5);
imshow(x);
title('Histogram Equalized image using own code');
subplot(3,2,6);
imhist(x);
axis tight;
title('Histogram Equalization using own code');

KẾT QUẢ :
Nhận xét :
Cột : tương ứng tần số suất hiện
Hàng : giá trị mức xám của ảnh
Về lượt đồ
Khi sử dụng hàm có sẵn , giá trị các cột cao hơn so với lượt đồ gốc , số
lượng các cột ít hơn và khoảng cách điều nhau , giá trị các cột gần bằng
nhau và chênh nhau không nhiều .
Khi sử không sử dụng hàm có sẵn thì , hình dáng lượt đồ tương tự với
lượt đồ gốc , ở bên phải số lượng các cột mỏng hơn còn bên trái số lượng
các cột nhiều hơn đứng xít nhau , giá trị các cột chênh nhau nhiều , và
tương tự như lược đồ gốc.
Về ảnh :
ảnh sau khi sử dụng hàm có sẵn và hàm tự code sẽ sáng hơn
------------------------- -------------------------------------------------------------------
Buổi 4.H1 = ¼ . [1 ; 2 ; 1] ; H2 = H1’ (Chuyển vị); I : ảnh xám
a, Tính Y1 = I * H1 Y2 = Y1 * H2
b, Gọi H = 1/16 [1 2 1;2 4 2;1 2 1] Tính Y3 = I * H
c, So sánh Y2 & Y3. Nhận xét 2 thuộc tính Y2 & Y3
CODE:
img = rgb2gray(imread('45.jpg'));
[h, w] = size(img)
H1 = [1 ;2 ;1] / 4;
H2 = transpose(H1);
Y1 = imfilter(img, H1,'same');
Y2 = imfilter (img, H2,'same');
subplot(2,2,1);
imshow(Y1,[]);
title('Y1');
subplot(2,2,2);
imshow(Y2,[]);
title('Y2');
H = [1 2 1; 2 4 2; 1 2 1] / 16;
Y3 = imfilter (img, H, 'same');
size(Y3);
subplot(2,2,3);
imshow(Y3,[]);
title('Y3');
subplot(2,2,4);
imshow(img,[]);
title('Original');
max(abs(Y2-Y1));
max(abs(Y3-Y2));

KẾT QUẢ:

Nhận xét :
Ta thấy ảnh Y2 và Y3 là giống nhau vì bộ lọc H của Y3 chính là bộ lọc
tách được và tách thành 2 bộ lọc 1 chiều là H1 = [1 ;2 ;1] / 4 và H2 =
transpose(H1) . khi khi chập ảnh với H1 và H2 thì sẽ nhanh hơn vì số
phép nhân được giảm xuống so với việc dùng bộ lọc H.
---------------------------------------------------------------------------------------------
Buổi 5: Dùng phương pháp nội suy song tuyến tính tìm giá trị ảnh từ
ảnh Mosaic
CODE:
img = imread('19.jpg');
[h, w, t] = size(img);
I = img;
I(2:2:h,:,1) = 0;
I(:,2:2:w,1) = 0;
I(1:2:h,1:2:w,2) = 0;
I(2:2:h,2:2:w,2) = 0;
I(1:2:h,:,3) = 0;
I(:,1:2:w,3) = 0;
imshow(I,[])
WRB = [1 2 1;2 4 2;1 2 1] / 4;
WG = [0 1 0; 1 4 1; 0 1 0] / 4;
I(:,:,1) = imfilter(I(:,:,1), WRB, 'replicate');
I(:,:,2) = imfilter(I(:,:,2), WG, 'replicate');
I(:,:,3) = imfilter(I(:,:,3), WRB, 'replicate');
figure
imshow(I,[])
Kết quả :

(ảnh ban đầu) (ảnh sau nội suy)


Nhận xét:
ảnh được tái tạo lại màu khá hoàn chỉnh , tuy nhiên khi phóng to ảnh lên
thì sẽ bị lỗi màu ở những chỗ có nhiều chi tiết (nhiều màu giao nhau).

---------------------------------------------------------------------------------------------
Buổi 6: Dùng phương pháp Alleyson để giải quyết bài toán demosaicing
CODE:
img = imread('anh.jpg');
[h, w, t] = size(img);
I = zeros(h,w);
I(1:2:h,1:2:w) = img(1:2:h,1:2:w,1);
I(1:2:h,2:2:w) = img(1:2:h,2:2:w,2);
I(2:2:h,1:2:w) = img(2:2:h,1:2:w,2);
I(2:2:h,2:2:w) = img(2:2:h,2:2:w,3);
FL = [-2 3 -6 3 -2;3 4 2 4 3;-6 2 48 2 -6;3 4 2 4 3;-2 3 -6 3 -2]/64;
lmn = conv2(I,FL,'same');
MC = I - lmn;
C = img;
mR = zeros(h,w);mG = zeros(h,w);mB = zeros(h,w);
mR(1:2:h,1:2:w) = 1;
mG(1:2:h,2:2:w) = 1;mG(2:2:h,1:2:w) = 1;
mB(2:2:h,2:2:w) = 1;
C1 = MC .* mR;
C2 = MC .* mG;
C3 = MC .* mB;
WRB = [1 2 1;2 4 2;1 2 1] / 4;
WG = [0 1 0; 1 4 1; 0 1 0] / 4;
res = img;
res(:,:,1) = conv2(C1,WRB,'same') + lmn;
res(:,:,2) = conv2(C2, WG,'same') + lmn;
res(:,:,3) = conv2(C3, WRB,'same') + lmn;
imshow(res,[])

(ảnh ban đầu) (ảnh sau khôi phục)


Nhận xét : ảnh được khôi phục màu khá hoàn chỉnh , lỗi màu được cải
thiện so với phương pháp nội suy song tuyến tính vì ảnh được chia thành
2 phần chrominance và luminance và chỉ nội suy trên thành phần
chrominance do đó hiện tượng sai màu được cải thiện hơn.

Buổi 7-8 không có bài tập


---------------------------------------------------------------------------------------------
Buổi 9
Chọn các hình: bãi biển, tòa nhà, nội thất, cây, người đi bộ Trộn phổ
biên độ của 5 hình trên, tìm cách tìm tương ứng

CODE:
img1 = imread('baibien.jpg');
img2 = imread('vatdung.jpg');
img3 = imread('dibo.jpg');
img4 = imread('cay.jpg');
img5 = imread('toanha.jpg');
images = {img1, img2, img3, img4, img5};
figure
for i = 1:length(images)
subplot(3,5,2*i-1)
imshow(images{i})
title(sprintf('Image %d',i))
end
for i = 1:length(images)
if size(images{i}, 3) == 3
images{i} = rgb2gray(images{i});
end
end
figure
for i = 1:length(images)
F = fftshift(fft2(double(images{i})));
F_mag = abs(F);
subplot(3,5,2*i-1+length(images))
imshow(log(1+F_mag), [])
title(sprintf('Image %d',i))
end

KẾT QUẢ
(1) (2) (3)

(4) (5)

---------------------------------------------------------------------------------------------

(a) (b) (c)


(d) (e)
tìm ảnh tương ứng với phổ biên độ
note : tất cả các ảnh điều có kích thước bằng nhau.

ta thấy
ảnh (d) sẽ tương ứng với (1) vì có nhiều góc cạnh nhất.nên sẽ có nhiều
đường chạy qua tâm thể hiện sự chuyển đổi mức năng lượng (các góc
cạnh) từ vùng này sang vùng khác trong ảnh.
ảnh (a) sẽ tương ứng với (3) vì có ít góc cạnh nhất
ảnh (c) sẽ tương ứng với (5) có các thành phần màu sắc tách biệt nhau
ảnh (e) sẽ tương ứng với (4) vì ảnh mang ít chi tiết nhất
ảnh (b) sẽ tương ứng với (2) còn lại

---------------------------------------------------------------------------------------------
Buổi 10 không có
Buổi 11
Câu 1 tìm biến đổi fourier của h(x)
câu 2.Gọi I là ảnh mosaic 1 lớp. Sử dụng các bộ lọc để lọc 1 cách hợp lý
và nhận xét
CODE:
img = imread('kodak/kodim19.png');
[h, w, t] = size(img);
I = zeros(h,w);
I(1:2:h,1:2:w) = img(1:2:h,1:2:w,1);
I(1:2:h,2:2:w) = img(1:2:h,2:2:w,2);
I(2:2:h,1:2:w) = img(2:2:h,1:2:w,2);
I(2:2:h,2:2:w) = img(2:2:h,2:2:w,3);
F = fft2(double(I));
[M, N] = size(I);
H1 = zeros(M, N);H2 = zeros(M, N);H3 = zeros(M, N);
D0 = 300;
n = 3;
F = fftshift(F);
for u = 1:M
for v = 1:N
d = sqrt((u - M/2)^2 + (v-N/2)^2);
if (d<=D0)
H1(u,v) = 1;
else
H1(u,v) = 0;
end
H2(u,v) = 1 / (1 + (d / D0)^(2*n));
H3(u,v) = exp(-d^2 / (2 * D0^2));
end
end
Sy1 = F .* H1;
Y1 = ifft2(ifftshift(Sy1));
Sy2 = F .* H2;
Y2 = ifft2(ifftshift(Sy2));
Sy3 = F .* H3;
Y3 = ifft2(ifftshift(Sy3));
subplot(1,3,1);
imshow(real(Y1), []);
subplot(1,3,2);
imshow(real(Y2), []);
subplot(1,3,3);
imshow(real(Y3), []);

KẾT QUẢ:

Nhận xét :
Bộ lọc thông thấp lý tưởng sẽ càng mượt khi D0 càng nhỏ và xuất hiện
hiện tượng gợn sóng
Bộ lọc thông thấp butterworth cũng sẽ có hiện tượng gợn sóng ở 1 số chỗ
, và tăng theo bậc của bộ lọc nhưng giảm hơn so với bộ lọc thông thấp lý
tưởng
Bộ lọc Gaussian thì trong miền tần số hay miền không gian điều có dạng
Gaussian do đó không có hiện tượng gợn sóng .
Câu 3

CODE:
imgList{1} = imread('cay.jpg');
imgList{2} = imread('dibo.jpg');
imgList{3} = imread('vatdung.jpg');
imgList{4} = imread('baibien.jpg');
imgList{5} = imread('toanha.jpg');
for t = 1:5
I = imgList{t};
subplot(3,5,t)
imshow(I);title("Image"+num2str(t));
I_gray = rgb2gray(I);
I = double(I_gray);
[M,N] = size(I);
SI = fftshift(fft2(I));
subplot(3,5,t+5)
imagesc(log(abs(SI)));title("Phổ"+num2str(t));
[u,v] = meshgrid(1:N,1:M);
u = u - (1+N)/2;
v = v - (1+M)/2;
u = u/N;v = v/M;
D = sqrt(u.^2+v.^2);
Hk = zeros(size(D));
Ek = zeros(1,50);
for i = 2:50
r1 = 0.01*(i-1);
r2 = 0.01*(i);
for x = 1:M
for y = 1:N
if (r1<=D(x,y)&&D(x,y)<r2)
Hk(x,y) = 1;
else
Hk(x,y) = 0;
end
end
end
Sk = SI.*Hk;
sum = 0;
for x = 1:M
for y = 1:N
sum = sum + abs(Sk(x,y))^2;
end
end
Ek(1,i) = sum;
end
subplot(3,5,t+5+5)
plot(Ek);title("EK("+num2str(t)+")");
end

KẾT QUẢ:

Nhận xét :
---------------------------------------------------------------------------------------------
Buổi 13

PHƯƠNG PHÁP K-Means


CODE:
rng(1);
X = [randn(100,2)*0.75+ones(100,2);
randn(100,2)*0.5-ones(100,2)];
figure;
scatter(X(:,1),X(:,2),10,'black');
title('Dữ liệu mẫu');
num_clusters = 2;
[idx, C] = kmeans_code(X, num_clusters);
figure;
scatter(X(idx==1,1),X(idx==1,2),10,'red');
hold on;
scatter(X(idx==2,1),X(idx==2,2),10,'blue');
scatter(C(:,1),C(:,2),50,'black','filled');
title('Phân loại dữ liệu sử dụng K-Means');
legend('Cụm 1','Cụm 2','Tâm cụm');

function [idx, C] = myKMeans(X, k)


[m, n] = size(X);
idx = randi(k, m, 1);
C = zeros(k, n);
for i = 1:k
C(i,:) = mean(X(idx==i,:));
end
maxIter = 100;
for iter = 1:maxIter
D = pdist2(X, C);
[~, idx] = min(D, [], 2);
for i = 1:k
C(i,:) = mean(X(idx==i,:));
end
end
end

KẾT QUẢ:
PHƯƠNG PHÁP DBSCAN
CODE:
data = dlmread('data.mat');
plot(data(:,1),data(:,2),'.','MarkerSize',10);
figure;
epsilon = 0.5;
minPts = 20;
[idx corepoints] = Dbscan(data, epsilon, minPts);

for i=1:size(data,1)
if(idx(i)==-1)
plot(data(i,1),data(i,2),'r+','MarkerSize',10);
hold on;
else
if(corepoints(i)==1)
plot(data(i,1),data(i,2),'b.','MarkerSize',15);
else
plot(data(i,1),data(i,2),'g*','MarkerSize',10);

end
hold on;
end
end
===========================================
function [labels, corepts] = DBscan(data, epsilon, minPts)
n = size(data, 1);
labels = zeros(n, 1);
corepts = false(n, 1);
clusterID = 0;
distances = pdist2(data, data);
for i = 1:n
if labels(i) ~= 0 || ~any(distances(i,:) <= epsilon)
continue;
end

clusterID = clusterID + 1;
labels(i) = clusterID;

neighbors = distances(i,:) <= epsilon;

if sum(neighbors) >= minPts


corepts(i) = true;
end
j = 1;
while j <= n
if neighbors(j) && labels(j) == 0
labels(j) = clusterID;

if sum(distances(j, neighbors)) >= minPts


corepts(j) = true;

neighbors = (distances(j,:) <= epsilon) | neighbors;


end
end
j = j + 1;
end
end
end
KẾT QUẢ:

PHÂN LOẠI DỮ LIỆU SỬ DỤNG DBSCAN


Trong thuật toán DBSCAN sử dụng hai tham số chính đó là:

minPts: Là một ngưỡng số điểm dữ liệu tối thiểu được nhóm lại
với nhau nhằm xác định một vùng lân cận epsilon có mật độ cao.
Số lượng minPts không bao gồm điểm ở tâm.
epsilon : Một giá trị khoảng cách được sử dụng để xác định vùng
lân cận epsilon của bất kỳ điểm dữ liệu nào.
Hai tham số trên sẽ được sử dụng để xác định vùng lân cận epsilon và
khả năng tiếp cận giữa các điểm dữ liệu lẫn nhau. Từ đó giúp kết nối
chuỗi dữ liệu vào chung một cụm.

Hai tham số trên giúp xác định ba loại điểm:

điểm lõi (core): Đây là một điểm có ít nhất minPts điểm trong vùng
lân cận epsilon của chính nó.
điểm biên (border): Đây là một điểm có ít nhất một điểm lõi nằm
ở vùng lân cận epsilon nhưng mật độ không đủ minPts điểm.
điểm nhiễu (noise): Đây là điểm không phải là điểm lõi hay điểm
biên.

Qui trình của thuật toán:

Bước 1: Thuật toán lựa chọn một điểm dữ liệu bất kì. Sau đó tiến
hành xác định các điểm lõi và điểm biên thông qua vùng lân cận
epsilon bằng cách lan truyền theo liên kết chuỗi các điểm thuộc
cùng một cụm.
Bước 2: Cụm hoàn toàn được xác định khi không thể mở rộng
được thêm. Khi đó lặp lại đệ qui toàn bộ quá trình với điểm khởi
tạo trong số các điểm dữ liệu còn lại để xác định một cụm mới.

Nhận xét :
So sánh thuật toán DBSCAN vs k-means
Kết quả cho thấy DBSCAN tạo ra các cụm được phân chia có tính tổng
quát hoá hơn đối với các trường hợp đặc biệt như hình tròn bao quan
hình tròn, hai đường cong úp vào nhau, các cụm với kích thước to và
nhỏ khác nhau.
Ưu điểm :DBSCAN : không cần biết trước số cụm
Nhược điểm :Tuy nhiên việc chọn epsilon, minPts là tương đối khó khăn
nếu không biết rõ dữ liệu .
---------------------------------------------------------------------------------------------
BUỔI 14 –NHẬN DIỆN BIỂN BÁO (sử dụng python)

CODE:
import cv2
import numpy as np

def empty(a):
pass
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None,
scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y],
(imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]=
cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1],
imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] =
cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver

def getContours(img):
contours,hierarchy =
cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_
NONE)
for cnt in contours:
area = cv2.contourArea(cnt)
print(area)
if area>500:
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt,True)
#print(peri)
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
print(len(approx))
objCor = len(approx)
x, y, w, h = cv2.boundingRect(approx)

path = 'bienso2.jpg'
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",78,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",116,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",0,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",21,255,empty)
cv2.createTrackbar("Val Min","TrackBars",231,255,empty)
cv2.createTrackbar("Val Max","TrackBars",253,255,empty)

while True:
img = cv2.imread(path)
imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
print(h_min,h_max,s_min,s_max,v_min,v_max)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHSV,lower,upper)
imgResult = cv2.bitwise_and(img,img,mask=mask)

imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgResult,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)

imgBlank = np.zeros_like(img)
imgStack = stackImages(1,([img,imgGray,imgBlur],
[imgCanny,imgContour,imgBlank]))
cv2.imshow("Stack", imgStack)

cv2.waitKey(1)

KẾT QUẢ:
Phương pháp này là phương pháp phát hiện vùng vật dựa trên không gian
màu HSV
Ưu điểm : phân vùng với độ chính xác cao
Nhược điểm : phải làm thủ công , 1 số biển có màu trùng với màu xung
quanh thì việc tách màu ra rất khó khan.

Các bước thực hiện


Bước 1
tạo các trackbar và lấy hình ảnh.
Bước 2
tách ra màu cần thiết (màu biển số xe) dựa vào giá trị của trackbar
Bước 3
tìm trọng tâm của vùng cần tìm
Bước 4
Khoanh vùng biển số

You might also like