You are on page 1of 6

Cân bằng Histogram

1 Thuật toán
1.1

Thuật toán

Cho ảnh nguồn gồm N mức xám (0, 1, …, N – 1).
Cần cân bằng histogram về M mức xám (0, 1, …, M – 1). Lưu ý: M, N có thể khác nhau
Bước 1: Tính pin(k) là xác suất xuất hiện của điểm ảnh có mức xám k (0 ≤ k ≤ N – 1) trong ảnh
gốc.
k

Bước 2: Tính tổng (tích lũy) sk =

∑ p (i )
i =0

in

Bước 3: Lập bảng thay thế T(k) = ROUND ( sk * (M – 1) ) với 0 ≤ k ≤ N – 1.
Do 0 ≤ sk ≤ 1 nên 0 ≤ T(k) ≤ M – 1
Bước 4: Với mỗi điểm trong ảnh nguồn có giá trị mức xám là k, thay thế điểm ảnh này với mức
xám mới là T(k). Ảnh nhận được có tối đa M mức xám (từ 0 đến M – 1)
1.2

Ví dụ

! Ví dụ 1: Xét ảnh 8 mức xám (0,1, …7) với kích thước 64 x 64. Số điểm ảnh thuộc mỗi mức xám
được cho trong bảng dưới đây:
K=Mức xám Nk=số điểm ảnh
0
790
1
1023
2
850
3
656
4
329
5
245
6
122
7
81
Yêu cầu: cân bằng Histogram về 8 mức xám (0, 1, …, 7)
Bước 1: Tính xác suất xuất hiện của điểm ảnh có mức xám k (k=0, 1, …, 7)
Mức xám k Số điểm ảnh Nk
0
790
1
1023
2
850
3
656
4
329
5
245
6
122
7
81

pin(k)
0.19
0.25
0.21
0.16
0.08
0.06
0.03
0.02

1200

0.3

1000

0.25

800

0.2

600

0.15

400

0.1

200

0.05

0

0
0

1

2

3

4

5

6

7

(a) Histogram chưa chuẩn hóa

0

1

k

∑ p (i )
i =0

in

0

s 0 = ∑ p in (ri ) = p in (r0 ) = 0.19
i =0
1

s1 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) = 0.44
i =0
2

s 2 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + p in (r2 ) = 0.65
i =0
3

s 3 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + L + p in (r3 ) = 0.81
i =0
4

s 4 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + L + p in (r4 ) = 0.89
i =0
5

s 5 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + L + p in (r5 ) = 0.95
i =0
6

s 6 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + L + p in (r6 ) = 0.98
i =0
7

s 7 = ∑ p in (ri ) = p in (r0 ) + p in (r1 ) + L + p in (r7 ) = 1.00
i =0

3

4

5

(b) Histogram đã chuẩn hóa

Hình 1. Histogram của ảnh gốc

Bước 2: Tính tổng (tích lũy) sk =

2

6

7

Bước 3: Tính giá trị bảng thay thế T(k)
T[0] = ROUND(s0 * 7) = ROUND(0.19 * 7) = ROUND(1.33 ) = 1
T[1] = ROUND(s1 * 7) = ROUND(0.44 * 7) = ROUND(3.08 ) = 3
T[2] = ROUND(s2 * 7) = ROUND(0.65 * 7) = ROUND(4.55 ) = 5
T[3] = ROUND(s3 * 7) = ROUND(0.81 * 7) = ROUND(5.67 ) = 6
T[4] = ROUND(s4 * 7) = ROUND(0.89 * 7) = ROUND(6.23 ) = 6
T[5] = ROUND(s5 * 7) = ROUND(0.95 * 7) = ROUND(6.65 ) = 7
T[6] = ROUND(s6 * 7) = ROUND(0.98 * 7) = ROUND(6.86 ) = 7
T[7] = ROUND(s7 * 7) = ROUND(1.00 * 7) = ROUND(7.00 ) = 7
Bước 4: Với mỗi điểm ảnh có giá trị mức xám là k trong ảnh gốc, thay thế bằng giá trị T(k)
Kết quả nhận được:
pout(k)
0.00
0.19
0.00
0.25
0.00
0.21
0.24
0.11

Mức xám k Số điểm ảnh Nk
0
0
1
790
2
0
3
1023
4
0
5
850
6
950
7
448
1200
1000
800
600
400
200
0
0

1

2

3

4

5

6

7

Hình 2. Histogram của ảnh kết quả (ví dụ 1)

! Ví dụ 2: Với ảnh gốc được cho trong ví dụ 1, hãy cân bằng histogram về ảnh gồm 6 mức xám
(0,1, …5)
Bước 1 và bước 2: tương tự ví dụ 1
Bước 3: Tính giá trị bảng thay thế T(k)
T[0] = ROUND(s0 * 5) = ROUND(0.19 * 5) = ROUND(0.95 ) = 1
T[1] = ROUND(s1 * 5) = ROUND(0.44 * 5) = ROUND(2.20 ) = 2
T[2] = ROUND(s2 * 5) = ROUND(0.65 * 5) = ROUND(3.25 ) = 3
T[3] = ROUND(s3 * 5) = ROUND(0.81 * 5) = ROUND(4.05 ) = 4
T[4] = ROUND(s4 * 5) = ROUND(0.89 * 5) = ROUND(4.45 ) = 4
T[5] = ROUND(s5 * 5) = ROUND(0.95 * 5) = ROUND(4.75 ) = 5
T[6] = ROUND(s6 * 5) = ROUND(0.98 * 5) = ROUND(4.99 ) = 5
T[7] = ROUND(s7 * 5) = ROUND(1.00 * 5) = ROUND(5.00 ) = 5
Bước 4: Với mỗi điểm ảnh có giá trị mức xám là k trong ảnh gốc, thay thế bằng giá trị T(k)
Kết quả nhận được:
Mức xám k Số điểm ảnh Nk
0
0
1
790
2
1023
3
850
4
985
5
448

pout(k)
0.00
0.19
0.25
0.21
0.24
0.11

1200
1000
800
600
400
200
0
0

1

2

3

4

5

Hình 2. Histogram của ảnh kết quả (ví dụ 2)

2 Các thao tác liên quan đến histogram trên OpenCV
2.1

Một số hàm cơ bản
Tạo mảng để chứa thông tin histogram

int

hist_size = 256;

// số lượng mức xám trong ảnh

// tạo mảng 1 chiều có khả năng chứa hist_size phần tử
CvHistogram* hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY);

Tính histogram trên ảnh mức xám
// tính histogram của ảnh mức xám gray_img
// và ghi nhận kết quả vào mảng 1 chiều hist.
cvCalcHist( &gray_img, hist, 0, NULL );

Xác định giá trị nhỏ nhất, giá trị lớn nhất, chỉ số tương ứng với giá trị nhỏ nhất và giá trị lớn
nhất trong mảng 1 chiều hist
cvGetMinMaxHistValue( hist, &min_value, &max_value, &min_idx, &max_idx);

Lấy giá trị của phần tử thứ i trong histogram
Cách 1:
cvGetHistValue_1D(hist,i);
Cách 2:
cvGetReal1D(hist->bins,i)

Chuẩn hóa histogram: sau khi chuẩn hóa, tổng giá trị các phần tử trong mảng hist sẽ bằng 255
cvNormalizeHist(hist, 255);

Cân bằng histogram: cho ảnh mức xám img, cần cân bằng histogram và nhận được kết quả là
ảnh result (lưu ý: cần tạo ra ảnh result có kích thước phù hợp và có 1 kênh màu)
IlpImage*
result = cvCreateImage(cvSize(img->width, img->height), 8, 1);
cvEqualizeHist(img, result);

2.2

Cân bằng histogram cho ảnh màu

Phương án 1:
-

Tách ảnh màu (gốc) thành 3 kênh màu (R, G, B). (gợi ý: dùng hàm cvCvtPixToPlane)

-

Cân bằng histogram cho từng kênh màu (R, G và B). (gợi ý: dùng hàm cvEqualizeHist)

-

Kết hợp 3 kênh màu (sau khi đã cân bằng histogram) thành 1 ảnh màu kết quả mới (gợi ý: dùng
hàm cvCvtPixToPlane)

Phương án 2:
-

Chuyển ảnh màu (gốc) sang hệ màu HSV (gợi ý: dùng hàm cvCvtColor)

-

Tách ảnh màu (hệ HSV) thành 3 kênh (H, S, V). (gợi ý: dùng hàm cvCvtPixToPlane)

-

Cân bằng histogram cho kênh V (gợi ý: dùng hàm cvEquilizeHist)

-

Kết hợp 3 kênh (H, S và Vmới) để nhận được ảnh kết quả trong hệ HSV (gợi ý: dùng hàm
cvCvtPlaneToPix)

-

Chuyển ảnh kết quả (trong hệ HSV) sang hệ RGB thông thường (dùng hàm cvCvtColor)

! Yêu cầu: Sinh viên tự cài đặt và kiểm tra hiệu quả (tốc độ xử lý, chất lượng ảnh kết quả) khi cân
bằng histogram cho ảnh màu theo 2 phương án trên. Cho bíết phương án nào thường cho kết quả tốt
hơn?
Trần Minh Triết
03/2007