Thị giác máy tính với OpenCV-Python Bài 4, Phần 10: Cân bằng biểu đồ

Thị giác máy tính với OpenCV-Python Bài 4, Phần 10: Cân bằng biểu đồ

Thị giác máy tính với OpenCV-Python Bài 4, Phần 10: Cân bằng biểu đồ

11:24 - 06/01/2022

Chúng ta sẽ tìm hiểu các khái niệm về cân bằng biểu đồ và sử dụng nó để cải thiện độ tương phản trong hình ảnh của chúng ta.

Thị giác máy tính với OpenCV-Python Bài 7 Phần 3: Nhận diện khuôn mặt
Thị giác máy tính với OpenCV-Python Bài 7 Phần 2: Phát hiện người đi bộ trong video
Thị giác máy tính với OpenCV-Python Bài 7 Phần 1: Phát hiện người đi bộ trong hình ảnh
Thị giác máy tính với OpenCV-Python Bài 6 Phần 2: Phép trừ nền
Thị giác máy tính với OpenCV-Python Bài 6 Phần 1: Bắt bám đối tượng với Meanshift và Camshift

Khái niệm

Hãy xem xét một hình ảnh có giá trị pixel chỉ giới hạn trong một số phạm vi cụ thể. Lấy ví dụ: hình ảnh sáng hơn sẽ có tất cả các pixel bị giới hạn ở các giá trị cao. Nhưng một hình ảnh tốt sẽ có các pixel từ tất cả các vùng của hình ảnh. Vì vậy, đôi khi chúng ta cần phải “cân bằng biểu đồ” để cải thiện độ tương phản của hình ảnh. Dưới đây là đoạn code minh họa:

  1. import cv2
  2. import numpy as np
  3. from matplotlib import pyplot as plt
  4. img = cv2.imread('wiki.jpg', 0)
  5. hist,bins = np.histogram(img.flatten(), 256, [0,256])
  6. cdf = hist.cumsum()
  7. cdf_normalized = cdf * hist.max() / cdf.max()
  8. plt.plot(cdf_normalized, color = 'b')
  9. plt.hist(img.flatten(), 256, [0,256], color = 'r')
  10. plt.xlim([0,256])
  11. plt.legend(('cdf', 'histogram'), loc = 'upper left')
  12. plt.show()

Kết quả:

 

Bạn có thể thấy biểu đồ nằm ở vùng sáng hơn, trong khi chúng ta cần toàn bộ quang phổ. Để làm được điều đó, chúng ta cần một hàm chuyển đổi ánh xạ các điểm ảnh đầu vào ở vùng sáng hơn thành các điểm ảnh đầu ra trong vùng đầy đủ. Đó là những gì cân bằng biểu đồ thực hiện.

Cân bằng biểu đồ trong OpenCV

OpenCV có một hàm để làm điều này, đó là cv2.equalizeHist(). Đầu vào của nó là hình ảnh thang độ xám và đầu ra là hình ảnh cân bằng biểu đồ mà chúng ta cần.

Dưới đây là một đoạn code minh họa đơn giản cho thấy cách sử dụng của nó cho cùng một hình ảnh ở trên:

  1. img = cv2.imread('wiki.jpg', 0)
  2. equ = cv2.equalizeHist(img)
  3. res = np.hstack((img, equ)) #stacking images side-by-side
  4.  
  5.  cv2.imshow(‘Equalized Image’, res)
  6. cv2.waitKey(0)
  7. cv2.destroyAllWindows()

Kết quả:

 

 

Bây giờ bạn có thể chụp các hình ảnh khác nhau với những điều kiện ánh sáng khác nhau, cân bằng nó và kiểm tra kết quả.

Cân bằng biểu đồ chỉ hoạt động tốt khi biểu đồ của hình ảnh được giới hạn trong một vùng cụ thể và sẽ không hoạt động tốt ở những nơi có sự thay đổi cường độ lớn, nơi biểu đồ bao phủ một vùng rộng lớn, tức là cả pixel sáng và tối đều có mặt.

CLAHE (Cân bằng biểu đồ thích ứng có giới hạn tương phản)

Thao tác cân bằng biểu đồ ở trên mà chúng ta vừa thực hiện đã xem xét độ tương phản toàn cục của hình ảnh. Trong nhiều trường hợp, đó không phải là một ý tưởng ​​hay. Lấy ví dụ: hình ảnh bên dưới hiển thị hình ảnh đầu vào và kết quả của nó sau khi cân bằng biểu đồ toàn cục. Kết quả thực hiện đoạn code như ở trên, chỉ thay bằng hình ảnh đầu vào khác đi:

 

 

Đúng là độ tương phản nền đã được cải thiện sau khi cân bằng biểu đồ. Nhưng hãy so sánh khuôn mặt của bức tượng trong cả hai hình ảnh: độ sáng quá cao làm mất hầu hết chi tiết khuôn mặt. Đó là vì biểu đồ không bị giới hạn trong một vùng cụ thể như trong trường hợp trước đó.

Để giải quyết vấn đề này, cân bằng biểu đồ thích ứng được sử dụng. Trong đó, hình ảnh được chia thành các khối nhỏ (Kích thước mặc định 8x8 trong OpenCV). Sau đó, mỗi khối này được cân bằng biểu đồ như bình thường. Lúc này, biểu đồ sẽ giới hạn trong một khu vực nhỏ (trừ khi có nhiễu). Nếu có nhiễu, nó sẽ được khuếch đại. Để tránh điều này, giới hạn độ tương phản được áp dụng. Nếu bất kỳ ngăn biểu đồ nào vượt quá giới hạn tương phản được chỉ định (theo mặc định là 40 trong OpenCV), các pixel đó sẽ được cắt bớt và phân phối đồng nhất đến các ngăn khác trước khi áp dụng cân bằng biểu đồ. Đoạn code dưới đây cho thấy cách áp dụng CLAHE trong OpenCV:

  1. import numpy as np
  2. import cv2
  3. img = cv2.imread('statue.jpg', 0)
  4. # create a CLAHE object (Arguments are optional).
  5. clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
  6. cl1 = clahe.apply(img)
  7. res = np.hstack((img, cl1))
  8. 11.imshow(‘CLAHE Equalization’, res)
  9. 12.waitKey(0)
  10. 13.destroyAllWindows()

 Xem kết quả bên dưới và so sánh với kết quả bên trên, đặc biệt là vùng tượng:

 

 

Ở phần tiếp theo chúng ta sẽ cùng tìm hiểu cách trích xuất một vùng đối tượng mong muốn trong hình ảnh dựa trên histogram.

 

(Sưu tầm)
VIỆN IMC
Tòa nhà IMC Tower, Số 176 Trường Chinh, Phường Khương
Thượng, Quận Đống Đa, Thành phố Hà Nội, Việt Nam
Tel/Fax : (+84) 24 3566 6232 / 24 3566 6234
Email: contact@imc.org.vn   Website: https://imc.org.vn