Tải bản đầy đủ (.pdf) (52 trang)

Tìm hiểu về ảnh Bitmap

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.37 MB, 52 trang )

0

E

BÀI TẬP LỚN MÔN HỌC
Xử Lý Ảnh
Nội dung
Tìm hiểu định dạng ảnh *.BMP
Các thao tác với file *.BMP trên C++
Chuyển ảnh màu sang ảnh đa mức xám
Phân ngưỡng ảnh
Phép mở ảnh
Một số nhận xét

Nhóm bài tập lớn 5 - Nhóm học 4



Mục lục
I.Thông tin nhóm ----------------------------------------------------------------------------------------------------------------------- 2
II.Nội dung báo cáo -------------------------------------------------------------------------------------------------------------------- 3
1.Tìm hiểu định dạng file ảnh *.BMP ------------------------------------------------------------------------------------------ 3
1.1.File ảnh *.BMP được hiểu như thế nào?------------------------------------------------------------------------------ 5
1.2.Định dạng Bitmap là gì ? -------------------------------------------------------------------------------------------------- 5
1.3.Cấu trúc tập tin ảnh bitmap (File structure) -------------------------------------------------------------------------- 7
1.4.Kích thước lưu trữ file *.bmp ------------------------------------------------------------------------------------------- 10
1.5.Kỹ thuật nén ảnh bitmap ------------------------------------------------------------------------------------------------ 10
1.6.Ví dụ cụ thể 1 file bmp --------------------------------------------------------------------------------------------------- 11
1.7.Ưu, khuyết điểm và ứng dụng của *.BMP --------------------------------------------------------------------------- 12
2.Các thao tác với file *.bmp trên C++ ---------------------------------------------------------------------------------------- 13
2.1.Chuyển ảnh màu sang ảnh đa mức xám ----------------------------------------------------------------------------- 20


2.2.Phân ngưỡng ảnh(Nhị phân hóa) -------------------------------------------------------------------------------------- 24
2.1.1.Thuật toán đẳng liệu ------------------------------------------------------------------------------------------------ 25
2.1.2.Thuật toán đối xứng ------------------------------------------------------------------------------------------------ 30
2.1.3.Thuật toán tam giác ------------------------------------------------------------------------------------------------- 31
2.3.Các Phép Toán Hình Thái Học------------------------------------------------------------------------------------------- 33
2.3.1.Phép mở ảnh(Opening) -------------------------------------------------------------------------------------------- 33
2.3.2.Phép co(Erosion) ----------------------------------------------------------------------------------------------------- 33
2.3.3.Phép giãn nở(Dilation) ---------------------------------------------------------------------------------------------- 35
3.Một số nhận xét từ kết quả thu được: ------------------------------------------------------------------------------------- 44
3.1.Phân ngưỡng --------------------------------------------------------------------------------------------------------------- 44
3.2.Phép mở ảnh --------------------------------------------------------------------------------------------------------------- 49


Báo cáo bài tập lớn môn học: Xử Lý Ảnh
I.Thông tin nhóm
Môn học Xử Lý Ảnh
Giảng viên Phạm Văn Sự
Nhóm học tín chỉ Nhóm 4 – Học phòng 102 A2- Kíp 5- Thứ 5
Nhóm bài tập lớn Nhóm số 5
Danh sách sinh viên trong nhóm

Họ và tên

Mã sinh viên

1. Nguyễn Hữu Hiếu

B15LDCN003

2. An Thị Kim Huệ


B15LDCN008

3. Nguyễn Trịnh Thị Huyền

B15LDCN007


II.Nội dung báo cáo
1.Tìm hiểu định dạng file ảnh *.BMP



1.1.File ảnh *.BMP được hiểu như thế nào?
BMP là viết tắt của “BitMap Picture”. Một file ảnh *.bmp được hiểu là một ảnh có định dạng bitmap.

1.2.Định dạng Bitmap là gì ?


Bitmap là một định dạng file để lưu trữ hình ảnh kỹ thuật số dưới dạng lưới (Raster)



Định dạng bitmap được Microsoft Corp tạo ra vào năm 1994. Nó là một định dạng ổn định và
được sử dụng phổ biến trên Windows kể từ phiên bản Windows 3.0.



Các thuộc tính tiêu biểu của một tập tin bitmap:



Bit per pixel (Số bit trên mỗi điểm ảnh) hay độ sâu màu thường được ký hiệu bởi n. Một
ảnh BMP n-bit có 2𝑛 màu. Giá trị n càng lớn thì ảnh càng có nhiều màu. Một số giá trị
tiêu biểu của n:


n= 1: Ảnh 2 màu, ảnh nhị phân, điển hình là ảnh trắng đen.



n= 4: Ảnh 16 màu




n= 8: Ảnh 256 màu.Điển hình là ảnh đa mức xám.



n= 16 (ảnh 65536 màu)



n= 24 (ảnh 16 triệu màu). Ảnh BMP 24-bit có chất lượng hình ảnh trung thực
nhất:



Chiều cao của ảnh (height) xác định bởi số điểm ảnh (pixel).Ví dụ ảnh có chiều cao 10px




Chiều rộng của ảnh (width) xác định bởi số điểm ảnh (pixel).Ví dụ: ảnh có chiều rộng 5px


1.3.Cấu trúc tập tin ảnh bitmap (File structure)


(en.wikipedia.org)


Giải thích sơ bộ
Tên cấu trúc

Độ lớn

Mục đích

Chú thích

Bitmap file header

14 bytes

Để lưu trữ các

Cho biết định dạng file là bitmap,

thông tin chung


kích thước file, và vị trí bắt đầu của

về các tập tin hình

nội dung file

ảnh bitmap

Không cần thiết sau khi các tập tin
được nạp vào bộ nhớ của thiết bị
hiển thị

Bitmap Information

40 bytes

Lưu một số thông

Cho biết chiều rộng, chiều cao, số

tin chi tiết giúp

lượng màu sắc sử dụng.

hiển thị ảnh
Color Palette

4*x bytes

Định nghĩa các


Gồm nhiều bộ có kích thước 4 bytes

màu sử dụng

xếp liền nhau theo cấu trúc: Blue –

trong ảnh

Green – Red – Reserved
x là số màu sử dụng trong ảnh

Bitmap Data

Tùy thuộc

Dùng để lưu dữ

Chứa giá trị màu của các điểm ảnh

vào file

liệu ảnh

trong * .bmp
Các điểm ảnh được lưu theo thứ tự
từ trái qua phải trên 1 dòng và các
dòng được lưu theo thứ tự dưới lên
trên.
Mỗi byte trong vùng bitmap data

biểu diễn 1 hoặc nhiều điểm ảnh tùy
theo số bits trên 1 pixel.

Xem phần 2: Các thao tác cơ bản trong C++ với file bmp để hiểu chi tiết hơn về phần cấu trúc file
bitmap
Khái niệm Padding bytes( bộ nhớ đệm): Thực tế khi một mảng các pixel được nạp vào bộ nhớ, mỗi hàng
phải bắt đầu tại một địa chỉ bộ nhớ mà địa chỉ đó là bội số của 4. Nhưng do ta chỉ có sử dụng 3 bytes cho
mỗi pixel nên mỗi dòng có thể kết thúc với địa chỉ không chia hết cho 4. Vì vậy trong mỗi dòng sẽ có
những padding bytes để hạn chế/bù đắp số byte thiếu và đảm bảo rằng kết thúc mỗi dòng địa chỉ bộ


nhớ luôn là bội số của 4. Ví dụ như ảnh có kích thước 10x14 (14 là width) thì padding sẽ là 2 bytes vì:Số
byte= 14 x 3 = 42 (nhân 3 vì 3 là số byte trong mỗi pixel) và 42mod4 = 2(42 chia 4 được 10 dư 2). Còn
nếu bức ảnh có kích thước 3x4 (4 là width) thì padding sẽ là 0 vì 4x3 = 12 và 12mod4 = 0.

1.4.Kích thước lưu trữ file *.bmp
Như đã nói ở phần Padding bytes, kích thước của mỗi hàng(width) sẽ được làm tròn tới bội số của 4
byte. Đối với hình ảnh có chiều cao(height) > 1, nhiều padding bytes sẽ được lưu trữ liên tục và tạo
thành Pixel array. Tổng số byte cần thiết để lưu trữ trên một hàng pixel có thể được tính như sau:

(en.wikipedia.org)


Lưu ý: Dấu ngoặc này có nghĩa là lấy phần nguyên dưới.



Tổng số lượng byte cần thiết để lưu trữ một mảng các điểm ảnh.Với n bit trên mỗi điểm ảnh
(bpp), với 2𝑛 màu sắc, có thể được tính bằng cách như sau
(en.wikipedia.org)




Dễ dàng hiểu: Dung lượng thật sự để lưu trữ ảnh sẽ bé hơn hoặc bằng dung lượng file trong bộ
nhớ.

1.5.Kỹ thuật nén ảnh bitmap


Ảnh có thể được nén 4-bit hoặc 8-bit bằng thuật toán RLE hoặc Huffman1D.



Các ảnh có độ sâu màu là 16bpp và 32bpp luôn được lưu trữ không nén



Ảnh có thế hoàn toàn lưu trữ mà không sử dụng kỹ thuật nén nào nếu muốn


1.6.Ví dụ cụ thể 1 file bmp

(en.wikipedia.org)


1.7.Ưu, khuyết điểm và ứng dụng của *.BMP
Ưu Điểm




Định dạng file này mang toàn bộ các ưu điểm của phương thức lưu trữ ảnh dạng raster. Ngoài
ra, do sử dụng công nghệ nén không tổn hao nên ảnh *.BMP có độ sắc nét và màu sắc tươi tắn
cao.



Dễ dàng dịch ra thành định dạng điểm (dot-format) để xuất ra các thiết bị như màn hình CRT,
máy in. Và thích hợp để sử dụng trong in ấn.



Độ tương thích cao trên nền tảng Windows

Khuyết điểm


Như trên, do là lưu trữ ảnh dạng raster và không sử dụng công nghệ nén hiệu quả nên *.BMP sẽ
bị vỡ ảnh, nhòe ảnh nếu ta thay đổi kích thước và cần có dung lượng rất lớn để lưu trữ. Ngày
nay những hình ảnh chúng ta trông thấy trên internet là hình ảnh có công nghệ nén gây tổn hao
để giảm không gian lưu trữ như *.jpeg.



Định dạng *.BMP không hỗ trợ chế độ nền trong suốt, có nghĩa là: Ảnh *.BMP chỉ có thể hiển thị
dạng hình chữ nhật, nên ngày nay với yêu cầu đồ họa luôn ưu tiên hàng đầu cho các phần mềm,
website. Chúng ta hay sử dụng các định dạng khác như *.PNG trong việc thiết kế.


2.Các thao tác với file *.bmp trên C++



Xây dựng cấu trúc riêng để thao tác đọc file *.bmp



Hàm chuyển ảnh bmp sang ảnh đa mức xám



Phân ngưỡng ảnh



Phép mở ảnh

Như đã đề cập ở phần tìm hiểu về file *.bmp, chúng ta biết được cấu trúc của tập tin ảnh bitmap. Vì thế
cần xây dựng các struct để lưu lại dữ liệu về file bitmap
Cấu trúc Pixel
struct Pix
{
unsigned char B;
unsigned char G;
unsigned char R;
};
B,G,R là giá trị của 3 màu Blue, Green, Red tại mỗi điểm ảnh.


Cấu trúc bitmap
struct BitMap
{

short

m_signature;

long

m_reserved1;

long

m_reserved2;

long

m_dataOffSet;

long

m_size;

long

m_width;

long

m_height;

short


m_planes;

short

m_bpp;

long

m_compression;

long

m_sizeImage;

long

m_xPixelsPreMeter;

long

m_yPixelsPreMeter;

long

m_colorsUsed;

long

m_colorsImportant;


};


Mô tả

(Xem lại hình ảnh cấu trúc ở phần 1.3 để hiểu rõ hơn)

m_signature Kiểu file (File bitmap thì sẽ có giá trị BM)
m_size Kích thước của file (byte)
m_reserved Phần dự trữ, có giá trị được quyết định bởi phần mềm tạo ra file
bitmap
_data_Offset offset của dữ liệu của hình ảnh (Tính từ vị trí bắt đầu của file bitmap
là 0)
m_width, m_height Chiều dài và chiều rộng của bức ảnh (tính theo pixel)
m_planes Đối với bitmap, giá trị buộc phải bằng 1
m_bpp Số bit trên mỗi pixel của ảnh, thông dụng có giá trị 24 (8bits cho mỗi
kênh R-G-B)
m_compression Kiểu nén của ảnh
m_sizeImage Kích thước của ảnh
m_xPixelsPreMeter Độ phân giải ngang của ảnh
m_yPixelsPreMeter Độ phân giải dọc của ảnh
m_color_used Số màu có trong color table (Thường là 0 do color table không được
sử dụng)
m_color_important Số index cần để hiện thị hình ảnh (Đối với index color table)


Hàm đọc file bitmap
void readBMP(const char* filePath, BitMap &header, char* &data)
{
FILE* f = fopen(filePath, "rb");

if (!f)
{
printf("Cannot open file for reading!!!");
exit(-1);
}
fread(&header, sizeof(header), 1, f);
int _padding = header.m_width % 4;//Đọc phần Padding bytes ở trên để hiểu tại sao lại chia 4 lấy
dư.
int _size = header.m_width * header.m_height * (header.m_bpp / 8) + _padding *
header.m_height;
data = new char[_size];
fread(data, sizeof(char), _size, f);
fclose(f);
}


Hàm ghi file bitmap
void writeBMP(const char* filePath, BitMap &header, char* &data)
{
FILE* f = fopen(filePath, "wb");
if (!f)
{
printf("Cannot open file for writing!!!");
exit(-1);
}
fwrite(&header, sizeof(header), 1, f);
int _padding = header.m_width % 4;
int _size = header.m_width * header.m_height * (header.m_bpp / 8) + _padding *
header.m_height;
fwrite(data, sizeof(char), _size, f);

fclose(f);
}


Chuyển data của 1 ảnh bitmap vào một mảng các Pixel
Pix* convertDataToPixelArray(char* &data, BitMap &header)
{
int _size = header.m_width * header.m_height;
Pix* _pixels = new Pix[_size];
int _padding = header.m_width % 4;
char* _temp = data;
for (int i = 0; i < header.m_height; i++)
{
for (int j = 0; j < header.m_width; j++)
{
_pixels[i * header.m_height + j].B = *(_temp++);
_pixels[i * header.m_height + j].G = *(_temp++);
_pixels[i * header.m_height + j].R = *(_temp++);
}
_temp += _padding;
}
return _pixels;
}


Chuyển dữ liệu từ mảng các Pixel vào data của 1 ảnh bitmap
char* convertPixelArrayToData(Pix* &pixels, BitMap &header)
{
int _padding = header.m_width % 4;
int _size = header.m_width * header.m_height * (header.m_bpp / 8) + _padding *

header.m_height;
char* _data = new char[_size];
char* _temp = _data;
for (int i = 0; i < header.m_height; i++)
{
for (int j = 0; j < header.m_width; j++)
{
*(_temp++) = pixels[i * header.m_height + j].B;
*(_temp++) = pixels[i * header.m_height + j].G;
*(_temp++) = pixels[i * header.m_height + j].R;
}
for (int k = 0; k < _padding; k++)
{
*(_temp++) = 0;
}
}
return _data;
}


2.1.Chuyển ảnh màu sang ảnh đa mức xám
Giải thích về thuật toán: Như đã tìm hiểu phần trên, ảnh bitmap sử dụng bảng màu RGB và dĩ nhiên
tuân theo luật phối màu cộng. Hay rõ hơn, để có được màu như ý trên mỗi điểm ảnh, thường dùng 8bits
để quy định cho mỗi kênh màu, và mỗi kênh màu với cường độ sáng thích hợp khi phối lại với nhau sẽ
cho ra màu như ý muốn.Vậy tổng cường độ sáng của 3 kênh chính là cường độ sáng tại điểm đó. Đây là ý
tưởng chính để chúng ta xây dựng thuật toán chuyển từ ảnh màu sang ảnh đa mức xám. Và dễ thấy,
đơn giản nhất. Chỉ cần lấy cường độ sáng của mỗi kênh cộng lại với nhau rồi chia 3 ta sẽ có kết quả
mong muốn.
Ix, y = ( Redx, y + Greenx, y + Bluex, y ) / 3



I(x, y): Là cường độ sáng tại điểm ảnh (x, y) của ảnh xám.



Red(x, y): Là giá trị của kênh màu Red(Đỏ) tại điểm ảnh (x, y) của ảnh màu(RGB).



Green(x, y): Là giá trị của kênh màu Green(Xanh lá cây) tại điểm ảnh (x, y) của ảnh màu(RGB).



Blue(x, y): Là giá trị của kênh màu Blue(Xanh lơ) tại điểm ảnh (x, y) của ảnh màu(RGB).

Tuy nhiên mặt khác theo khoa học đã chứng minh thì mắt người nhạy cảm hơn với thành phần màu
xanh lá cây và màu đỏ so với xanh da trời nên ta có công thức sau:
Ix, y = 0.3086 * Redx, y + 0.6094 * Greenx, y + 0.0820 * Bluex, y
Ix, y = 0.299 * Redx, y + 0.587 * Greenx, y + 0.114 * Bluex, y
Hoặc cũng có thể sử dụng công thức:
Ix, y = ( 2 * Redx, y + 5 * Greenx, y + 1 * Bluex, y ) / 8
(Thực hiện phép nhân trong miền số nguyên thì nhanh hơn rất nhiều trong miền số thực)
Tuỳ theo yêu cầu nên có thể linh hoạt trong việc sử dụng các công thức trên.


Hàm chuyển ảnh màu sang đa mức xám:
void rgb2gray()
{
for (int i = 0; i < size; i++)//Duyệt tất cả các điểm ảnh
{

int dosang = (pixels[i].R + pixels[i].G + pixels[i].B) / 3;//Để đẩy nhanh tốc độ tính toán và
mức độ của chương trình là đơn giản nên tôi sử dụng công thức này, có thể dùng công thức khác tùy vào
yêu cầu.
pixels[i].R = pixels[i].G = pixels[i].B = dosang;// luật phối màu cộng: 3 kênh màu R, G, B có
giá trị bằng nhau sẽ cho ra màu xám
}
}


Hình ảnh minh họa
Ảnh minh họa được tạo từ phần mềm Paint trên Win10 và save lại ở định dạng 24bits bitmap
Ảnh màu 24bits


Ảnh sau khi xử lý


2.2.Phân ngưỡng ảnh(Nhị phân hóa)
Là quá trình biến đổi một ảnh đa mức xám thành ảnh chỉ còn 2 mức là trắng và đen.
Tôi gọi giá trị cường độ sáng tại một điểm ảnh là I(x,y) .
INP(x,y) là cường độ sáng của điểm ảnh trên ảnh nhị phân .
(Với 0 < x < image.width) và (0 < y < image.height).
Để biến đổi ảnh xám thành ảnh nhị phân. Ta so sánh giá trị cường độ sáng của điểm ảnh với một
ngưỡng nhị phân T.
Nếu I(x,y) > T thì INP(x, y) = 0 (0).
Nếu I(x,y) > T thì INP(x, y) = 255 (1).
Hàm phân ngưỡng
void phannguong()
{
for (int i = 0; i < size; i++)//Duyệt tất cả các điểm ảnh

{
int dosang = pixels[i].R;//lấy ra giá trị của mỗi điểm
if(dosang<=t)//Nếu giá trị bé hơn hoặc bằng ngưỡng T
{
pixels[i].R = pixels[i].G = pixels[i].B =0;//Thay đổi giá trị tại các điểm ảnh đó thành
0
}
if(dosang>t) //Nếu giá trị lớn hơn ngưỡng T {
pixels[i].R = pixels[i].G = pixels[i].B =255; ;//Thay đổi giá trị tại các điểm ảnh đó
thành 255
}
}
}


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×