Xin chào các bạn, hôm nay chúng ta sẽ cùng tìm hiểu về histogram, cân bằng biểu đô mức xám và phân loại ảnh sử dụng histogram.
Ôn lại bài tuần 2
Đâu tiên, chúng ta sẽ điểm qua các kiến thức về phép toán trên điểm ảnh trong bài viết trước.
- Lấy mẫu, lượng tử hóa
- Biến đổi trên điểm ảnh -> chỉnh độ sáng, độ tương phản
- Gamma
- Negation
- Kết hợp ảnh
- Tính trung bình
- Trừ background
Histogram
1. Khái niệm
Histogram (lược đồ xám) là biểu đồ tần xuất thống kê số lần xuất hiện các mức sáng trong ảnh.
2. Cách tính histogram
- là mức xám của ảnh
- là số điểm ảnh (pixels) có giá trị
- Biểu đồ mức xám chưa chuẩn hóa (unnormalized histogram) của được định nghĩa như sau: với , là số mức xám.
- Biểu đồ chuẩn hoá (normalized histogram): với M, N là chiều dài và chiều rộng của hay là của ảnh
3. Ví dụ
Ta lần lượt có ảnh và histogram tương ứng với các ảnh drank, light, low-contrast và high-contrast
![](https://i.2kvn.com/img/vib-2021-b1f3d4fe-b563-4e38-943a-96c08faaf0a9.png)
- Với ảnh dark thì histogram có các cột tập trung vào bên trái tương ứng với màu tối
- Với ảnh light thì histogram có tập trung vào bên phải chứa các pixel trắng
- Với ảnh độ tương phản thấp (low-contrast) thì histogram có các cột tập trung xít nhau và ở giữa
- Với ảnh độ tương phản cao (high-contrast) thì histogram san đều với các giá trị
4. Code
Giả sử ta có bức ảnh độ tương phản như sau:
![](https://i.2kvn.com/img/vib-2021-5d5bcdee-bc24-445b-9fa8-7ce470b65edc.jpg)
import numpy as np import cv2 import matplotlib.pyplot as plt %matplotlib inline
plt.rcParams['figure.figsize'] = [10,8]
img = cv2.imread("low-exposure.jpg", 0)
Chúng ta bắt đầu thử bắt đầu code nào . Ta có 2 cách dùng hàm để tính histogram.
- Sử dụng cv2.calcHist từ thư viện OpenCV
# using cv2.calcHist()
hist = cv2.calcHist( [img], channels = [0], mask=None, # full image histSize=[256], #full scale ranges=[0,256]
)
plt.plot(hist)
- Sử dụng hàm numpy.histogram
#using numpy
h2 = np.histogram(img.ravel(), bins=256, range=[0,256])
print(h2[0].shape)
plt.plot(h2[0])
Và 2 cách trên đều ra kết quả như sau:
![](https://i.2kvn.com/img/vib-2021-616964b8-4dda-4fd9-bd54-a55dd1de8899.png)
Histogram equalization (cân bằng biểu đồ mức xám)
1. Khái niệm
Phần này là phần mình giới thiệu và chứng minh công thức, nếu thấy quá dài dòng và khó hiểu bạn có thể xem luôn phần các bước làm.
Trong trường hợp ảnh là một hàm liên tục, ta xét biến đại diện cho các cấp độ xám của ảnh cần được cân bằng và trong khoảng với đại diện cho đen và đại điện cho trắng. Cân bằng biểu đồ mức xám là tìm một ánh xạ khi đó mỗi điểm ảnh có giá trị trong ảnh ban đầu sẽ được ánh xạ tạo nên cấp độ trong ảnh đẩu ra.
Ta cần tìm hàm thỏa mãn các điều kiện sau:
- là hàm đơn vị và đơn điệu tăng trong khoảng
- với
Ở đây ta định nghĩa hàm và lần lượt biểu diễn hàm mật độ xác suất của các biến ngẫu nhiên và . Kết quả cơ bản từ lý thuyết xác suất là nếu cho trước và , thỏa mãi điều kiện 1. thì hàm mật độ xác xuất có thể thu được bằng cách sử dụng công thức sau:
![](https://i.2kvn.com/img/vib-2021-ca4529ac-b0c4-4343-ad88-ca859277347c.png)
Do đó, hàm mật độ xác suất của , được quyết định bởi cấp độ xám PDF của ảnh đầu vào và hàm biến đổi đã chọn. Một hàm biến đổi quan trọng trong xử lý ảnh có dạng:
![](https://i.2kvn.com/img/vib-2021-87224c73-17fc-4e11-b7bc-c816f38b4a29.png)
Đẳng thức bên phải của phương trình trên được gọi là hàm phân phối tích lũy của biến ngẫu nhiên , nó đơn điệu tăng thỏa mãn điều kiện 1). Tương tự, tích phân của hàm mật độ xác suất trong khoảng cũng nằm trong khoảng nên điều kiện 2 được thỏa mãn. Ta có:
![](https://i.2kvn.com/img/vib-2021-99837478-7439-40b4-bfba-c3fe947ea8ad.png)
![](https://i.2kvn.com/img/vib-2021-2f8a91a8-4e2c-4918-af2e-0456a474cbc0.png)
Thay kết quả này cho cho phương trình (3 -10), và do tất cả các giá trị xác suất đều dương, ta thu được:
![](https://i.2kvn.com/img/vib-2021-08094bf3-3020-4054-bb32-8f39b82950b4.png)
Ta thấy là hàm phân bố xác suất đều, từ đó có thể kết luận rằng việc thực hiện phép biến đổi (3-14) đã sinh ra biến ngẫu nhiên với hàm phân bố xác suất đều.
Khi ảnh là các giá trị độ sáng rời rạc, ta làm việc với xác suất xuất hiện của từng giá trị độ sáng và phép toán tổng xác suất thay vì hàm mật độ xác suất và phép toán tích phân. Xác suất xuất hiện của mức xám trong ảnh được tính xấp xỉ bằng . Lúc này công thức cho phép biến đổi tương tự trong phương trình (3-10) trên các giá trị rời rạc là:
![](https://i.2kvn.com/img/vib-2021-162b1bd1-9a45-426d-8fe6-e353a78988ae.png)
Vậy sau 1 hồi dài dòng để tìm ra công thức , ta có các bước làm.
2. Các bước làm
- Tính toán histogram
- Chuẩn hóa histogram cho về khoảng [0, 1] :
- Tính hàm xác suất mật độ
- Tính giá trị mức xám cho từng điểm ảnh: O(x, y) = round( T(I(x,y)) )
Ta có ví dụ để cho trực quan hơn. Ta có bảng phân phối cường độ và giá trị histogram cho hình ảnh kỹ thuật số 3 bit ảnh 64 * 64
![](https://i.2kvn.com/img/vib-2021-574aa348-8848-4239-aac8-1f472e4609b0.png)
Theo công thức ta sẽ tính được
L = 8
![](https://i.2kvn.com/img/vib-2021-9af383dd-4c92-4204-85a0-3c6d4cc42b0c.png)
Sau đó ta sẽ chuyển đổi giá trị của từng điểm ảnh như sau:
![](https://i.2kvn.com/img/vib-2021-a2c296d5-58c0-4d97-8c7f-3a653d761732.png)
3. Code
Ta sẽ sử dụng bức ảnh bên trên để cân bằng histogram
Cách 1 ta dùng thủ công thì hàm cân bằng histogram như sau:
def hist_equalize(img): # 1. calclate hist hist = cv2.calcHist([img], [0], None, [256], [0, 256]) # 2. normalize hist h, w = img.shape[:2] hist = hist/(h*w) # 3. calculate CDF cdf = np.cumsum(hist) s_k = (255 * cdf - 0.5).astype("uint8") return s_k
Tiếp theo ta phải ánh xạ mức xám đầu vào với s_k:
s_k = hist_equalize(img)
equalized_img = cv2.LUT(img, s_k)
plot_img_and_hist(equalized_img)
Cách 2 ta sẽ dùng hàm của OpenCv như sau:
img_equalized = cv2.equalizeHist(img)
plot_img_and_hist(img_equalized)
Và kết quả ta sẽ được như sau, bên trai là ảnh đẩu ra và bên phải là histogram và cdf tương ứng.
![](https://i.2kvn.com/img/vib-2021-e6e937eb-8a8a-4809-8d69-64899edb4a55.png)