thuc_hanh
TRANSCRIPT
![Page 1: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/1.jpg)
1
NỘI DUNG
Bài 1: Làm quen với code xử lý ảnh
- Hiển thị ảnh
- Đọc pixel ảnh
- Thay đổi giá trị cho pixel ảnh
- Copy ảnh
- Lưu ảnh
Bài 2: Xử lý cơ bản
- Xử lý độ sáng
- Âm bản
- Vẽ hình chữ nhật
Bài 3: Histogram
- Biến đổi ảnh xám
- Histogram
Bài 4: Ảnh nhị phân
- Biến đổi ảnh nhị phân
- Co/dãn ảnh nhị phân
Bài 5: Phát hiện biên (border)
- Phương pháp gradient
- Kỹ thuật Laplace
- Phương pháp Canny
Bài 6: Phân vùng ảnh
- Thuật toán k-means
![Page 2: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/2.jpg)
2
Bài thực hành số 1:
Làm quen với code xử lý ảnh
Mục tiêu của bài thực hành này là sinh viên có thể sử dụng ngôn ngữ lập
trình java để thực hiện một số thao tác ban đầu có tính chất nền tảng để có thể
xử lý ảnh số về sau:
- Đọc được một ảnh số và lưu vào bộ nhớ đệm; Đồng thời lấy được một
số thông tin chung như chiều rộng, chiều cao
- Đọc được giá trị màu của 1 pixel với đầy đủ 3 thành phần Red, Green,
Blue
- Sửa đổi giá trị màu của 1 pixel bằng cách thay đổi 1 trong 3 thành phần
màu Red, Green, Blue
- Thực hiện việc nhân bản (copy) ảnh trong bộ nhớ đệm
- Lưu ảnh đã xử lý thành một file với tên tùy ý
Đó cũng là yêu cầu mà sinh viên cần làm được sau buổi thực hành.
Bài thực hành được thực hiện bằng ngôn ngữ java với phần mềm Eclipse.
1. Đọc ảnh từ file
Một số thư viện cần sử dụng để thao tác với ảnh như sau
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;
import java.net.URL;
Việc đọc ảnh được thực hiện dễ dàng với phương thức read của class
ImageIO. Giả sử chúng ta muốn đọc file ảnh C:\img1.jpg ta làm như sau:
BufferedImage image = null;
try {
File file = new File(“C:/img1.jpg”);
image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
![Page 3: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/3.jpg)
3
Ở đó, image là đối tượng lưu nội dung ảnh trong bộ nhớ đệm. Đối tượng
image có thể mang kiểu Image thay vì kiểu BufferedImage. Tuy nhiên, trên
thực tế, người ta hay dùng kiểu BufferedImage hơn kiểu Image.
Việc đọc file ảnh qua mạng có thể được thực hiện bằng cách sử dụng lớp
URL. Giả sử chúng ta cần đọc file ảnh http://ktcn-dqt.edu.vn/img1.jpg thì
chúng ta thay dòng code số 3 thành:
URL file = new URL(“http://ktcn-dqt.edu.vn/img1.jpg”);
Yêu cầu thực hành:
- Tìm 1 file hình trong máy tính
- Tạo một lớp với tên là Têncủabạn_Bai1 sau đó thực hiện đoạn code
trên trong hàm main sao cho không bị lỗi
- Tạo phương thức public BufferedImage readImage(String imgPath) để
đọc ảnh biết rằng imgPath là đường dẫn file ảnh và giá trị trả về chính
là bộ đệm của ảnh
2. Hiển thị file ảnh
Chúng ta có thể hiển thì một ảnh từ bộ đệm ảnh được lưu trong một đối
tượng kiểu BufferedImage trên một form bằng đoạn code đơn giản sau:
public void view(BufferedImage image) {
JFrame frame = new JFrame();
frame.setSize(300, 300);
JLabel label = new JLabel(new ImageIcon(image));
frame.add(label);
frame.setVisible(true);
}
Muốn thực hiện đoạn code này cần sử dụng thêm một số thư viện:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
Yêu cầu thực hành:
- Thêm phương thức trên vào chương trình
- Cho trước đường dẫn của một file ảnh, yêu cầu hiển thị một file ảnh đó
lên một form
![Page 4: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/4.jpg)
4
3. Đọc thông tin ảnh
Với đối tượng BufferedImage, ta có thể đọc được kích thước của ảnh
tương ứng là chiều cao và chiều rộng.
Yêu cầu thực hành:
- Tạo phương thức tên info(BufferedImage) với tham số nhận vào là đối
tượng thuộc kiểu BufferedImage. Phương thức này hiển thị chiều cao
và chiều rộng của ảnh. Giả sử ảnh có chiều cao là 100 pixel và chiều
rộng là 200 pixel thì phương thức hiển thị:
Kich thuoc anh (Dimensions): 200x100
4. Đọc pixel ảnh
Yêu cầu thực hành:
- Tạo phương thức tên pixelColor(BufferedImage, int, int) nhận vào
một đối tượng ảnh, chỉ số cột x và chỉ số hàng y của anh. Phương thức
hiển thị các giá trị màu: Red, Green, Blue theo mẫu ví dụ: Color tai Pixel(10, 30) la:
- Red: 234
- Green: 37
- Blue: 126
Hướng dẫn:
Trong lớp BufferedImage có phương thức getRGB(x,y)trong đó x là
chỉ số cột và y là chỉ số hàng trong ma trận ảnh. Phương thức này trả về giá trị
màu kiểu int của pixel tại vị trí (x,y) của ảnh. Giả sử giá trị màu đó là c. Ta tách các màu red, green, blue bằng cách tạo đối tượng Color với giá trị màu
này
Color color = new Color(c);
Sau đó, sử dụng đối tượng color để chiếc xuất ra các màu tương ứng
5. Thay đổi giá trị cho pixel ảnh
Giả sử chúng ta có 3 giá trị màu thành phần tương ứng của red, green, blue
là (r, g, b). Ta thực hiện việc gán giá trị màu này cho pixel(x, y) theo 2 bước
- Tạo màu từ 3 giá trị này bằng new Color(r, g, b)
- Sử dụng phương thức setRGB(x, y, colorRGB) của đối tượng
BufferedImage để thay đổi giá trị của pixel(x, y) bằng giá trị mới là
colorRGB.
![Page 5: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/5.jpg)
5
Yêu cầu thực hành:
- Tăng giá trị của từng thành phần màu của mỗi pixel lên ½ giá trị ban
đầu sau đó hiển thị ảnh kết quả. Cho nhận xét ảnh kết quả.
Lưu ý: Giá trị màu của mỗi thành phần màu phải luôn nằm trong
ngưỡng từ 0 đến 255.
- Thay đổi giá trị màu của từng pixel bằng cách giữ nguyên giá trị màu
của thành phần Green. Đồng thời, đặt giá trị mới cho red và blue là 0.
Hãy hiển thị kết quả. Cho nhận xét ảnh kết quả.
6. Copy ảnh
Yêu cầu thực hành
- Thực hiện việc xử lý theo yêu cầu ở câu 5 sau đó hiển thị đồng thời ảnh
ban đầu và ảnh sau khi xử lý.
Hướng dẫn:
- Trước khi xử lý ảnh, ta thực hiện việc copy bộ nhớ đệm sang biến mới
và xử lý ảnh ở biến mới này.
Ví dụ: Ta copy bộ nhớ đệm ảnh từ image sang imageNew.
BufferedImage imageNew = new BufferedImage(image.getWidth(),
image.getHeight(), image.getType());
imageNew.setData(image.getData());
Sau đó, ta thực hiện việc xử lý ảnh trên imageNew
7. Lưu ảnh
Yêu cầu thực hành
- Tạo phương thức save(BufferedImage, String) dùng để lưu lại một
đối tượng ảnh thành một file ảnh mới
- Thực hiện việc xử lý ảnh ở câu 5, sau đó lưu lại ảnh với tên của bạn
Hướng dẫn
- Việc lưu ảnh được thực hiện bằng phương thức write() của đối tượng
ImageIO
Ví dụ:
try {
File outputfile = new File(“C:/kq.jpg”);
ImageIO.write(image, “jpg”, outputfile);
} catch (IOException e) {}
![Page 6: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/6.jpg)
6
Bài tập thực hành số 2:
Xử lý ảnh cơ bản
Trong bài thực hành này, chúng ta sẽ thực hiện việc tăng/giảm độ sáng của
ảnh và thực hiện việc biến đổi âm bản.
Lưu ý: Bài thực hành này có thể phải sử dụng lại một số phương thức đã
cài đặt ở bài thực hành số 1. Vì vậy, sinh viên cần tập trung chúng lại với
nhau.
Hãy tạo lớp mới tên Họtêncủabạn_Bai2 sau đó thực hiện các công việc
sau:
1. Xử lý độ sáng
Việc xử lý độ sáng được thực hiện bằng cách tăng/giảm giá trị màu của
pixel cùng lên/xuống một đơn vị.
Ví dụ: Tại pixel(x, y) có giá trị màu là (234, 123, 89). Khi đó, nếu muốn
tăng độ sáng của pixel này lên 5 đơn vị thì pixel(x,y) có giá trị màu mới là
(239,128,94)
Yêu cầu thực hành:
- Tạo phương thức tên incBrightness() với đầu vào là một đối tượng
ảnh, đầu ra là đối tượng ảnh được tăng độ sáng.
Lưu ý: Phương thức chỉ tăng độ sáng lên 1 đơn vị so với ảnh đầu vào
- Tạo phương thức tên decBrightness() với đầu vào là một đối tượng
ảnh, đầu ra là đối tượng ảnh được giảm độ sáng.
Lưu ý: Phương thức chỉ giảm độ sáng xuống 1 đơn vị so với ảnh đầu
vào
- Tăng độ sáng lên 100 đơn vị sau đó lưu ảnh kết quả với tên
tang_100.jpg
- Giảm độ sáng xuống 100 đơn vị sau đó lưu ảnh kết quả với tên
giam_100.jpg
![Page 7: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/7.jpg)
7
2. Âm bản
Yêu cầu thực hành:
- Tạo phương thức amban() với đầu vào là một BufferedImage và đầu ra
là một BufferedImage đã được chuyển sang âm bản.
Hướng dẫn:
- Việc chuyển sang âm bản được thực hiện bằng cách thay đổi giá trị của
pixel theo cách sau:
Giá trị pixel mới = 255 – giá trị pixel cũ
Ví dụ: Pixel(x, y) có giá trị màu là (200, 54, 254) thì khi chuyển qua âm
bản, giá trị màu của nó tương ứng là (55, 201, 1)
3. Vẽ hình chữ nhật
Yêu cầu thực hành:
- Tạo phương thức rectangle() với đầu vào là một BufferedImage, hai
tọa độ (x1, y1), (x2, y2) và đối tượng Color. Phương thức có chức năng
vẽ hình chữ nhật có màu như đầu vào. Hình chữ nhật này nhận hai tọa
độ đầu vào làm hai đỉnh đối diện.
Hướng dẫn:
- Lần lượt gán giá trị màu Color như đầu vào cho các pixel sau
o Các pixel ở hàng y1 từ cột x1 đến cột x2
o Các pixel ở hàng y2 từ cột x1 đến cột x2
o Các pixel ở cột x1 từ hàng y1 đến hàng y2
o Các pixel ở cột x2 từ hàng y1 đến hàng y2
(x1, y1)
(x2, y2)
![Page 8: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/8.jpg)
8
Bài tập thực hành số 3:
Histogram
Nội dung chủ yếu trong bài thực hành này gồm 2 nội dung:
- Chuyển đổi ảnh màu sang ảnh xám (256 màu)
- Tạo histogram cho ảnh xám tìm được
1. Biến đổi ảnh xám
Ảnh xám có đặc trưng là 3 thành phần màu (red, green, blue) có giá trị
bằng nhau. Vì vậy, việc biến đổi sang ảnh xám được thực hiện dễ dàng bằng
cách cho giá trị của 3 thành phần màu của pixel có cùng giá trị như nhau. Giá
trị màu mới chính là giá trị trung bình của 3 thành phần màu trong ảnh gốc
(ảnh màu).
Ví dụ: Giả sử pixel(x, y) trong ảnh gốc có giá trị màu là (150, 230, 250).
Ta thấy 150 + 230 + 250 = 630. Giá trị trung bình của các thành phần màu
này là:
(150 + 230 + 250)/3 = 630/3 = 210
Điều đó có nghĩa, pixel(x, y) trong ảnh xám sẽ có giá trị màu tương ứng là
(210, 210, 210)
Yêu cầu thực hành:
- Đọc 1 file ảnh màu trên máy tính, sau đó chuyển ảnh đó sang ảnh xám
và lưu lại với tên là xam.jpg
2. Histogram
Chi tiết cách tính histogram được đề cập trong slide môn học!
Yêu cầu thực hành:
- Tạo phương thức histogram() với đầu vào là một ảnh xám. Phương
thức này trả về số pixel cùng màu trong ảnh ứng với từng giá trị màu cụ
thể theo mẫu sau
Mau 0: co 8 pixel
...
Mau 255: co 45 pixel
![Page 9: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/9.jpg)
9
Bài tập thực hành số 4:
Ảnh nhị phân
Ảnh nhị phân là ảnh chỉ có 2 màu duy nhất là đen và trắng. Trong bài thực
hành này, sinh viên cần thực hiện được 3 thao tác sau:
- Chuyển đổi một ảnh (màu hoặc xám) sang ảnh nhị phân.
- Co ảnh nhị phân xuống 1 đơn vị
- Giãn ảnh nhị phân lên 1 đơn vị
1. Biến đổi ảnh nhị phân
Ảnh nhị phân chỉ có 2 màu trắng và đen tương ứng với hai giá trị màu là
(255, 255, 255) và (0, 0, 0). Việc biến đổi ảnh nhị phân được thực hiện một
cách đơn giản bằng cách chọn ra một ngưỡng thresold. Những pixel nào có
giá trị màu ở mức xám nhỏ hơn thresold sẽ được gán giá trị màu là (0,0,0);
ngược lại thì được gán giá trị màu là (255,255,255). Thông thường giá trị
thresold được chọn là 127.
Yêu cầu thực hành:
- Tạo ra một phương thức tên binary() với đầu vào là một đối tượng
BufferedImage và đầu ra là đối tượng BufferedImage đã được nhị phân
hóa.
- Hãy thực hiện việc nhị phân hóa một ảnh xám sau đó lưu lại với tên là
xam_nhiphan.jpg
- Hãy thực hiện việc nhị phân hóa một ảnh màu sau đó lưu lại với tên là
mau_nhiphan.jpg
2. Co ảnh nhị phân
Chức năng này làm giảm số pixel đen của ảnh nhị phân. Điều đó có nghĩa
là chúng ta chuyển một số pixel từ màu đen sang màu trắng. Pixel đen được
chuyển giá trị sang màu trắng là những pixel đen nằm kề với ít nhất 1 pixel
trắng..
Muốn làm được điều đó, đầu tiên chúng ta nên tạo một phương thức để
kiểm tra xem một pixel nào đó có kề pixel trắng hay không. Nếu một pixel
nằm kề với ít nhất một pixel trắng, ta đổi giá trị của pixel đó sang màu trắng.
![Page 10: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/10.jpg)
10
Chức năng này có thể giảm nhiễu cho hình ảnh (những pixel đen nằm
riêng lẻ sẽ bị xóa)
Yêu cầu thực hành
- Tạo phương thức tên isBorderBlack() với đầu vào là một
BufferedImage và tọa độ (x, y) của pixel cần kiểm tra. Đầu ra của
phương thức là này giá trị bool với ý nghĩa: Nếu tọa độ (x, y) có kề
với pixel trắng thì phương thức trả về giá trị true, trái lại phương thức
trả về giá trị false.
- Tạo phương thức tên decBorder() với đầu vào là một
BufferedImage. Phương thức thực hiện việc co ảnh BufferedImage
xuống 1 đơn vị.
Lưu ý: Có thể phải thực hiện việc nhân bản ảnh (như câu 5 ở bài thực
hành số 1) trong quá trình co ảnh nhị phân.
3. Giãn ảnh nhị phân
Chức năng này tương tự chức năng co ảnh nhị phân. Chức năng này khác
với chức năng co ảnh nhị phân ở điểm:
- Chức năng co ảnh nhị phần chuyển những pixel đen nằm kề pixel trắng
sang màu trắng
- Chức năng giãn ảnh nhị phần chuyển những pixel trắng nằm kề pixel
đen sang màu đen.
Yêu cầu thực hành
- Tạo phương thức tên isBorderWhite() với đầu vào là một
BufferedImage và tọa độ (x, y) của pixel cần kiểm tra. Đầu ra của
phương thức là này giá trị bool với ý nghĩa: Nếu tọa độ (x, y) có kề
với pixel đen thì phương thức trả về giá trị true, trái lại phương thức
trả về giá trị false.
- Tạo phương thức tên incBorder() với đầu vào là một
BufferedImage. Phương thức thực hiện việc giãn ảnh BufferedImage
lên 1 đơn vị.
Lưu ý: Có thể phải thực hiện việc nhân bản ảnh (như câu 5 ở bài thực
hành số 1) trong quá trình giãn ảnh nhị phân.
![Page 11: thuc_hanh](https://reader031.vdocuments.mx/reader031/viewer/2022020207/557211f5497959fc0b8fc96a/html5/thumbnails/11.jpg)
11
Bài thực hành số 5:
Phát hiện biên
Bài thực hành này yêu cầu sinh viên thực hiện được việc tìm biên của một
ảnh xám. Do vậy, nếu đầu vào là một ảnh màu thì ta phải chuyển ảnh đó sang
ảnh xám (như câu 1 của bài thực hành số 3). Việc phát hiện biên được thực
hiện dựa vào các phương pháp sau
- Phương pháp Gradient
- Kỹ thuật Laplace
- Phương pháp Canny
Nhìn chung, việc phát hiện theo phương pháp nào ở trên đây cũng đều
dựa trên thao tác cơ bản là nhân ma trận.
Còn tiếp...