You are on page 1of 22

TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN

KHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO ĐỒ ÁN CÁ NHÂN


Môn: TOÁN ỨNG DỤNG VÀ THỐNG KÊ
CHO CÔNG NGHỆ THÔNG TIN
Lab03: Project02

Class: 21CLC010
MSSV: HỌ VÀ TÊN:
21127512 Nguyễn Lê Hoàng Kha
GVHD:
Vũ Quốc Hoàng
Nguyễn Văn Quang Huy
Ngô Đình Hy
Phan Thị Phương Uyên

Thành phố Hồ Chí Minh, Tháng 7 năm 2023


Mục lục

I. Mức độ hoàn thành ............................................................................................................... 3

II. Ý tưởng và giải thích ............................................................................................................. 4

1. Thay đổi độ sáng cho ảnh .................................................................................................... 4


2. Thay đổi độ tương phản ....................................................................................................... 6
3. Lật ảnh ngang dọc ................................................................................................................ 8
4. Chuyển đổi ảnh RGB thành ảnh xám/sepia ....................................................................... 10
5. Làm mờ, làm nét ảnh ......................................................................................................... 14
6. Cắt ảnh ở trung tâm ............................................................................................................ 19
7. Cắt ảnh hình tròn................................................................................................................ 20
III. Tham khảo ........................................................................................................................... 22
I. Mức độ hoàn thành

STT Yêu cầu Mức đô hoàn thành

1 Thay đổi độ sáng cho ảnh Đã hoàn thành

2 Thay đổi độ tương phản Đã hoàn thành

3 Lật ảnh (ngang – dọc) Đã hoàn thành

4 Chuyển đổi ảnh RGB thành ảnh xám / sepia Đã hoàn thành

5 Làm mờ / sắc nét ảnh Đã hoàn thành

6 Cắt ảnh theo kích thước (cắt ở trung tâm) Đã hoàn thành

7 Cắt ảnh theo khung hình tròn Đã hoàn thành


II. Ý tưởng và giải thích
1. Thay đổi độ sáng cho ảnh

a) Ý tưởng thực hiện

- Mỗi điểm màu được biểu diễn bằng giá trị trong khoảng [0,255], nếu giá trị càng tăng về cực
255 thì màu sẽ càng sáng, ngược lại nếu giá trị giảm về cực 0 thì màu sẽ càng tối.
- Với lý thuyết trên, dù ảnh đầu vào làm gray hay rgb thì ta chỉ cần cộng một scarlar vào tất cả
các channels màu của pixels thì ảnh sẽ sáng lên.

b) Giải thích hàm

- Hàm adjust_image_brightness() có tham số đầu vào gồm: img – mảng 3 chiều được reshape
thành mảng 2 chiều được lấy từ ảnh, inc_brightness_value – giá trị tăng độ sáng.
- Bước 1: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 2: cú pháp img_tmp += inc_brightness_value sẽ là phép ma trận cộng một scalar trong
numpy  tất cả các phần tử trong ma trận sẽ có giá trị tăng thêm inc_brightness_value.
- Bước 3: giới hạn giá trị của các phần tử trong mảng trong khoảng [0,255] bằng hàm where(),
do mảng đã được đổi kiểu dữ liệu từ int8 sang int32 khi lấy mảng từ ảnh nên sẽ tránh được
trường hợp overflow khi lấy các phẩn tử cộng cho một số.
- Bước 4: trả về mảng img_tmp
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

RGB chỉnh sáng

Xám chỉnh sáng


2. Thay đổi độ tương phản

a) Ý tưởng thực hiện

- Dựa vào thuật toán tăng độ tương phản “Constrast Stretching”, ta sẽ áp dụng ma trận nhân cho
scalar, hoặc có thể nói một mảng ndarray nhân cho scalar (Image Processing Algorithms Part
5: Contrast Adjustment, 2015).

b) Giải thích hàm

- Hàm adjust_image_contrast() có các tham số đầu vào gồm, img - mảng hai chiều được reshape
từ mảng ba chiều lấy từ ảnh, contrast_level – độ contrast mong muốn.
- Bước 1: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 2: tính giá trị cho contrast correction factor theo công thức sau:
259(𝐶 + 255)
𝐹= , 𝑣ớ𝑖 𝐹 𝑙à 𝑓𝑎𝑐𝑡𝑜𝑟, 𝐶 𝑙à 𝑐𝑜𝑛𝑡𝑟𝑎𝑠𝑡_𝑙𝑒𝑣𝑒𝑙
255(259 − 𝐶)
- Bước 3: lấy mảng img trừ cho 128, sau đó nhân lại cho factor và cộng lại 128.
- Bước 4: giới hạn các giá trị của mảng từ [0,255] bằng hàm np.where().
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

Ảnh RGB
tăng tương
phản

Ảnh xám
tăng tương
phản
3. Lật ảnh ngang dọc

a) Ý tưởng thực hiện

- Lật ảnh ngang thực chất là sự chuyển đổi vị trị các pixel đối xứng qua trục hoành có trục hoành
đi qua tâm ảnh và vuông góc với hai cạnh cắt ngang.
- Lật ảnh dọc thực chất là sự chuyển đổi vị trị các pixel đối xứng qua trục tung có trục tung đi
qua tâm ảnh và vuông góc với hai cạnh cắt ngang.

b) Giải thích hàm

- Hàm flip_image() có tham số truyền vào bao gồm: img – mảng 3 chiều được lấy từ ảnh gốc,
direction có các giá trị lần lượt 1, 2 tương ứng với lật ảnh dọc hay ngang.
- Bước 1: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 2: tùy vào giá trị direction mà ta thực hiện lật dọc hay ngang:
o Trường hợp lật dọc: chạy vòng lặp for w (chiều rộng ảnh) lần với i, ta gán giá trị cả cột thứ
i của img_tmp bằng giá trị cột thứ w – 1 – i của img  gán giá trị cột bằng giá trị đối xứng
bên kia với trục tung nêu trên.
o Trường hợp lật ngang: chạy vòng lặp for h (chiều cao ảnh) lần với i, ta gán giá trị cả dòng
thứ i của img_tmp bằng giá trị dòng thứ w – 1 – i của img  gán giá trị dòng bằng giá trị
đối xứng với trục hoành nêu trên.
- Bước 3: trả về mảng img_tmp
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

RGB
(xoay dọc)

Xám
(xoay
ngang)
4. Chuyển đổi ảnh RGB thành ảnh xám/sepia

a) Ý tưởng thực hiện

- RGB thành xám (Grayscale to RGB Conversion, n.d.):


o Sử dụng phương pháp weighted để tính toán phần trăm đóng góp của từng kênh màu của
RGB. Ta thu về ảnh xám có đúng một kênh màu với các pixel có giá trị:
𝑁𝑒𝑤 𝑔𝑟𝑎𝑦𝑠𝑐𝑎𝑙𝑒 𝑖𝑚𝑎𝑔𝑒 = (𝑎 × 𝑅) + (𝑏 × 𝐺) + (𝑐 × 𝐵)
𝑉ớ𝑖 𝑎, 𝑏, 𝑐 𝑙ầ𝑛 𝑙ượ𝑡 𝑙à 𝑝ℎầ𝑛 𝑡𝑟ă𝑚 đó𝑛𝑔 𝑔ó𝑝 𝑣à𝑜 𝑘ê𝑛ℎ 𝑚à𝑢 𝑥á𝑚 𝑐ủ𝑎 ả𝑛ℎ 𝑚ớ𝑖
o Ta tính phần trăm đóng góp a, b, c vào kênh màu xám mới bằng chính phần trăm đóng góp
của từng kênh màu R,G,B trong ảnh gốc  xét từng pixel ảnh với 3 màu đỏ, xanh lá, xanh
dương và chọn ra màu gần nhất với màu của pixel  ta tính được phần trăm a, b, c.
- RGB thành sepia (How to Convert a Color Image Into Sepia Image - Image Processing Project
- Dyclassroom | Have Fun Learning :-), n.d.):
o Tương tự như chuyển RGB thành xám, ta có sẵn công thức tính màu sepian dựa theo
phương pháp weighted như sau:

𝑅′ = (0.393 × 𝑅) + (0.769 × 𝐺) + (0.189 × 𝐵)


𝐺′ = (0.349 × 𝑅) + (0.686 × 𝐺) + (0.168 × 𝐵)
𝐵 = (0.272 × 𝑅) + (0.534 × 𝐺) + (0.131 × 𝐵)
o Giá trị RGB có các giá trị lần lượt thỏa điều kiện sau:
If R’ > 255 then r = 255 else r = R’
If G’ > 255 then g = 255 else g = G’
If B’ > 255 then b = 255 else b = B’
o Để tăng tốc độ của thuật toán, ta sẽ sử dụng hàm tích vô hướng np.dot của numpy.
b) Giải thích hàm

- Hàm adjust_image_channel có tham số đầu vào gồm: img – mảng hai chiều được reshape từ
mảng ba chiều khi lấy mảng từ ảnh, type – dùng để xác định kiểu chuyển đổi.
- Bước 1: gán biến h bằng giá trị của img.shape[0], tương đương số dòng của mảng.
- Bước 2: tùy vào giá trị của type mà ta thực hiện chuyển đổi gray hay sepia:
o Trường hợp gray:
 Bước 1: tạo một mảng hai chiều rgb gồm 3 màu red, green, blue tương ứng [255,0,0],
[0,255,0], [0,0,255]
 Bước 2: tạo một mảng hai chiều distances có kích thước (h,3) để lưu trữ dữ liệu
 Bước 3: cho i chạy trong khoảng 3, ta lần lượt tính khoảng cách của các pixel trong
img tới từng kênh màu rgb theo công thức sau:

(𝑎 − 𝑏 )

𝑣ớ𝑖 𝑐 𝑙à 𝑠ố 𝑙ượ𝑛𝑔 𝑐ℎ𝑎𝑛𝑛𝑒𝑙𝑠


𝑎, 𝑏 𝑙à 𝑡ọ𝑎 độ đ𝑖ể𝑚 𝑐ủ𝑎 ℎ𝑎𝑖 đ𝑖ể𝑚 đ𝑎𝑛𝑔 𝑥é𝑡
 Tại img – rgb[i]: chương trình sẽ broad cast mảng rgb[i] một chiều thành mảng hai
chiều có số dòng bằng số dòng của img, sau đó lấy giá trị từng dòng img trừ cho giá trị
của rgb[i].
 Ta bình phương tất cả các phần tử bằng **2 và cộng các cột bằng sum(axis = 1), cuối
cùng ta lấy căn giá trị từng dòng bằng **0.5.
Ta được mảng với số dòng bằng số các phần tử img với số cột bằng 3, tương ứng mỗi dòng
là khoảng cách của một điểm đến các kênh màu rgb.
 Bước 4: ta chọn ra vị trí gần nhất của từng điểm ảnh đến từng kênh màu rgb bằng hàm
np.argmin() và gán vào biến closest.
 Bước 5: ta lần lượt đếm số lượng điểm gần nhất với từng kênh màu rgb bằng hàm
np.count_nonzero(closest == i) với i = [0,2] tương ứng với r, g, b. Ta tính tổng total =
r + g + b và tạo mảng ratio có 3 phần tử là phần trăm đóng góp của ba kên màu r, g, b
tương ứng r/total, g/total, b/total.
 Bước 6: ta dùng hàm np.dot(img,ratio) để lần lượt tính tích vô hướng của từng điểm
pixel với ratio, ta sẽ được giá trị tương ứng với công thức new grayscale image đã nêu
trên. Cuối cùng ta trả về giá trị của hàm np.dot đấy.
o Trường hợp sepia:
 Bước 1: ta tạo một mảng hai chiều chứa phần trăm như công thức đã nêu trên
[[0.393,0.349,0.272],[0.769,0.686,0.534],[0.189,0.168,0.131]]
 Bước 2: ta tích vô hướng mảng img với sepia_ratio bằng hàm np.dot(), hàm sẽ cho ra
kết quả là mảng hai chiều với từng dòng là các giá trị mới R’, G’, B’, hệ thống hoạt
động theo ví dụ như sau:

 Hệ thống sẽ lấy giá trị từng cột trong sepia_ratio tích vô hướng với từng dòng trong
img. Giá trị output ở dòng 1 cột 1 = 1.351 = 0.393*1 + 0.769*1 + 0,189*1. Hệ thống
tiếp tục thực hiện phép tính và cho ra kết quả mới R’, G’, B’ như mong đợi.
 Bước 3: trả về values đã được giới hạn giá trị không lớn hơn 255 với hàm
np.where(values>255,255,values)
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

RGB thành
xám

Xám thành
sepia
5. Làm mờ, làm nét ảnh

a) Ý tưởng thực hiện

- Cả hai làm mờ và làm nét ảnh đều áp dụng phương pháp tích chập giữa kernel và image
với công thức và bảng kernel được cho như sau (Wikipedia contributors, 2023):

𝑔(𝑥, 𝑦) = 𝑤 × 𝑓(𝑥, 𝑦) = 𝑤(𝑑𝑥, 𝑑𝑦)𝑓(𝑥 − 𝑑𝑥, 𝑦 − 𝑑𝑦)

𝑉ớ𝑖 𝑔(𝑥, 𝑦) 𝑙à ả𝑛ℎ đã đượ𝑐 𝑙ọ𝑐, 𝑓(𝑥, 𝑦) 𝑙à ả𝑛ℎ 𝑔ố𝑐, 𝑤 𝑙à 𝑏ộ 𝑙ọ𝑐 𝑘𝑒𝑟𝑛𝑒𝑙
𝑇ấ𝑡 𝑐ả 𝑐á𝑐 𝑝ℎầ𝑛 𝑡ử 𝑐ủ𝑎 𝑘𝑒𝑟𝑛𝑒𝑙 𝑐ó 𝑔𝑖ớ𝑖 ℎạ𝑛 − 𝑎 ≤ 𝑑𝑥 ≤ 𝑎 𝑣à − 𝑏 ≤ 𝑑𝑦 ≤ 𝑏
- Box blur:
1 1 1 1
1 1 1
9
1 1 1
- Sharpen kernel:
0 −1 0
−1 5 −1
0 −1 0
b) Giải thích hàm

Blur:

- Hàm box_blur_image() có tham số đầu vào là img – mảng ba chiều được lấy từ ảnh
- Bước 1: gán giá trị kích thước của shape vào các biến h, w, c
- Bước 2: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 3: ta thực hiện thuật toán trên từng kênh màu, được xác định bằng z
- Bước 4: ta chạy hai vòng for để đi qua tất cả các điểm ảnh thuộc kênh màu z, tại điểm ảnh có
tọa độ [y,x,z] , ta thực hiện slicing ảnh gốc [y-1:y+2,x-1:x+2,z] để được vùng ảnh có 9 điểm
ảnh.
- Bước 5: lấy trung bình tổng 9 điểm ảnh như công thức với kernel đã nêu trên, gán giá trị nhận
được cho điểm ảnh img_tmp[y,x,z]
- Bước 6: trả về mảng được giới hạn giá trị trong khoảng [0.255] bằng hàm np.clip()
Sharpen:

- Hàm sharpen_image() có hàm số đầu vào là img – mảng ba chiều được lấy từ ảnh.
- Bước 1: tạo một mảng kernel được nên như trên.
- Bước 2: gán giá trị kích thước của shape vào các biến h, w, c
- Bước 3: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 4: ta chạy hai vòng for để đi qua tất cả các điểm ảnh thuộc kênh màu z, tại điểm ảnh có
tọa độ [y,x,z] , ta thực hiện slicing ảnh gốc [y-1:y+2,x-1:x+2,z] để được vùng ảnh có 9 điểm
ảnh.
- Bước 5: ta thực hiện tích chập mảng được slicing với kernel bằng phép nhân (*) hai mảng, sau
đó lấy tổng bằng ham sum(), xem ví dụ bên dưới để hiểu hơn:

o Giải thích: thực hiện phép nhân hai ma trận có cùng kích thước trong mảng numpy sẽ cho
ra kết quả:
𝑎 ⋯ 𝑎 𝑏 ⋯ 𝑏 𝑎 ×𝑏 ⋯ 𝑎 ×𝑏
𝐴×𝐵 = ⋮ ⋱ ⋮ + ⋮ ⋱ ⋮ = ⋮ ⋱ ⋮
𝑎 ⋯ 𝑎 𝑏 ⋯ 𝑏 𝑎 ×𝑏 ⋯ 𝑎 ×𝑏
- Bước 6: trả về mảng được giới hạn giá trị trong khoảng [0.255] bằng hàm np.clip()
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

Làm mờ
ảnh RGB

Làm nét
ảnh xám
6. Cắt ảnh ở trung tâm

a) Ý tưởng thực hiện

- Sử dụng slicing mảng ba chiều được lấy từ ảnh gốc để trả về mảng đã được cắt.

b) Giải thích hàm

- Hàm cut_image() có tham số đầu vào là mảng ba chiều được lấy từ ảnh gốc.
- Bước 1: tạo một img_tmp được sao chép từ img để tránh những thay đổi lên mảng gốc img.
- Bước 2: gán giá trị kích thước của shape vào các biến h, w, c.
- Bước 3: trả về mảng được slicing với kích thước như hình.

c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

Cắt ảnh ở
trung tâm
7. Cắt ảnh hình tròn

a) Ý tưởng thực hiện

- Ta tính khoảng cách từ tọa độ các điểm pixel ảnh đến tọa độ tâm hình tròn, nếu khoảng cách
từ điểm đó đến tâm hình tròn xa hơn bán kính được đặt trước thì ta tô đen điểm ảnh đó.

b) Giải thích hàm

- Hàm circle_img() có các tham số đầu vào gồm: img - ảnh hai chiều được reshape từ ảnh ba
chiều được lấy từ ảnh gốc, h và w lần lượt là chiều cao, chiều rộng của ảnh gốc.
- Bước 1: chọn bán kính r bằng ½ h hoặc ½ w tùy thuộc h hay w nhỏ hơn.
- Bước 2: chọn tọa độ center bằng [½ h, ½ w]
- Bước 3: sử dụng list comprehension để tạo mảng tọa độ của từng điểm ảnh trong mảng hai
chiều.
- Bước 4: tính khoảng cách từng tọa độ điểm đến tọa độ center và gán vào dist_from_center =
((cord - center)**2).sum(axis=1)**0.5
o Tại cord - center: chương trình sẽ broad cast mảng center một chiều thành mảng hai chiều
có số dòng bằng số dòng của cord, sau đó lấy giá trị từng dòng cord trừ cho giá trị của
center.
o Ta bình phương tất cả các phần tử bằng **2 và cộng các cột bằng sum(axis = 1), cuối cùng
ta lấy căn giá trị từng dòng bằng **0.5.
- Bước 5: gán các điểm ảnh = [0,0,0] có index tương ứng với index của mảng dist_from_center
lớn hơn hoặc bằng r.
- Bước 6: trả về mảng img_tmp
c) Kết quả

Hành động Trước khi chỉnh sửa Sau khi chỉnh sửa

Cắt ảnh
hình tròn
III. Tham khảo
Grayscale to RGB conversion. (n.d.). Tutorialspoint.

https://www.tutorialspoint.com/dip/grayscale_to_rgb_conversion

How to convert a color image into sepia image - Image Processing Project - dyclassroom | Have

fun learning :-). (n.d.). https://dyclassroom.com/image-processing-project/how-to-

convert-a-color-image-into-sepia-image

Image Processing Algorithms Part 5: Contrast adjustment. (2015, October 29). Dreamland

Fantasy Studios. https://www.dfstudios.co.uk/articles/programming/image-programming-

algorithms/image-processing-algorithms-part-5-contrast-adjustment/

Wikipedia contributors. (2023). Kernel (image processing). Wikipedia.

https://en.wikipedia.org/wiki/Kernel_(image_processing)

You might also like