You are on page 1of 15

PHÁT HIỆN ĐỐI TƯỢNG

3.1. Hiệu chuẩn camera

3.1.1. Hiệu chuẩn webcam

Thường ảnh hiển thị trên camera có độ phân quá cao và chương trình chạy quá chậm. Ta
cần hiệu chuẩn camera cho phù hợp, hiệu chuẩn camera là thay đổi các tham số của camera
− Tham thứ nhất của ảnh phải kể đến là Mat Figure và Mat image, ảnh xám hoặc
ảnh màu 8 bit.
− Tham số thứ hai, patternSize là số lượng hàng và cột ở góc trong của mỗi bảng.
Nói chung, số lượng hàng và cột không giống nhau sẽ thuận tiện cho chương trình
hiệu chuẩn tiếp theo để xác định hướng của bề mặt cần hiệu chuẩn
− Các góc tham số thứ ba được sử dụng để lưu trữ vị trí tọa độ hình ảnh góc bên
trong ảnh được phát hiện, thường được biểu thị bằng một vector:
Point2f: vector<Point2f> image_points_buf;
− Tham số thứ tư, flage, được sử dụng để xác định các cách khác nhau nhằm xử lý
các điểm góc bên trong trên bản đồ của bảng. Thường có các giá trị mặc định.
3.1.2. Thuật toán chuẩn hóa camera

− Hàm sử dụng
retval, corners=cv.findChessboardCorners(image, patternSize[, corners[,
flags]])

retval, centers=cv.findCirclesGrid(image, patternSize, flags, blobDetector,


parameters[, centers])

retval, centers=cv.findCirclesGrid(image, patternSize[, centers[, flags[,


blobDetector]]])

ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints,


gray.shape[::-1], None, None)

map1, map2=cv.initUndistortRectifyMap(cameraMatrix, distCoeffs, R,


newCameraMatrix, size, m1type[, map1[, map2]])

imagePoints, jacobian=cv.projectPoints(objectPoints, rvec, tvec, cameraMatrix,


distCoeffs[, imagePoints[, jacobian[, aspectRatio]]])

− Code mẫu
Sinh viên chạy code này và tìm hiểu từng câu lệnh để tìm hiểu thuật toán chú ý hàm
cv2.findChessboardCorners

import numpy as np
import cv2

51
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
cap = cv2.VideoCapture(0)
frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height=int(480/frame_width*frame_height)
ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)
while cap.isOpened():
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(image=gray, patternSize=(6, 4),
corners=None)
print(corners)
print('---------')
if ret == True:
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1),
criteria)
cv2.drawChessboardCorners(img, (6, 4), corners2, ret)
cv2.imshow('img', img)
key = cv2.waitKey(delay=10)
if key == ord("q"):
break
cv2.destroyAllWindows()

3.1.3. Bài tập mở rộng

Thường camera bị biến dạng xuyên tâm và biến dạng các thông số bên trong và bên ngoài
của camera.
Thông số bên trong là camera bao gồm thông tin về tiêu cự (fx, fy) và tiêu điểm quang
học (cx, cy), … hay còn được gọi là ma trận camera. Tất cả phụ thuộc vào máy ảnh vì nó chỉ
cần được tính toán một lần để biết cho sử dụng.
Chúng ta cần ít nhất 10 mẫu để hiệu chỉnh camera. Điểm 3D được gọi là điểm đối tượng
và điểm 2D được gọi là điểm ảnh.
Ngoài việc sử dụng lưới dạng board, chúng ta có thể sử dụng lưới tròn bằng hàm
cv2.findCirclesGrid() để tìm mẫu. Thực tế chức minh rằng sử dụng một mạng tinh thể tròn chỉ
cần một vài ảnh
− Viết chương trình sử dụng hàm cv2.findChessboardCorners()
− Viết chương trình sử dụng hàm cv2.findCirclesGrid()

52
3.2. Lập trình ứng dụng tìm xác định đối tượng trên ảnh

3.2.1. Xác định trọng tâm và đường bao của blob trên ảnh

a. Blob là gì?

Blob là một nhóm các pixel được kết nối trong một hình ảnh có chung một thuộc tính (Ví
dụ: giá trị thang độ xám). Trong hình 3.1, các vùng được kết nối là các đốm màu và mục tiêu
phát hiện blob là xác định và đánh dấu các vùng này.

Hình 3.1: Ảnh Blob


b. Hoạt động để phát hiện Blob

SimpleBlobDetector là một thuật toán blob đơn giản được mô tả như hình 3.2. Thuật toán
được điều khiển bởi các tham số sau.

Hình 3.2: Xác định hoạt động của ảnh Blob


− Ngưỡng (Thresholding): Chuyển đổi ảnh gốc thành ảnh nhị phân bằng giá trị ngưỡng
ảnh gốc với các ngưỡng bắt đầu từ minThreshold. Các ngưỡng này được tăng
từ thresholdStep cho đến maxThreshold. Vì vậy, ngưỡng đầu tiên

53
là minThreshold, ngưỡng thứ hai là minThreshold + thresholdStep, ngưỡng thứ ba
là minThreshold + 2 x thresholdStep ,…
− Nhóm (Grouping): Trong mỗi hình ảnh nhị phân, các pixel trắng được kết nhóm lại
với nhau ta gọi đó là những blob nhị phân này.
− Kết hợp (Merging): Trọng tâm của các blob trong ảnh nhị phân được tính toán và các
blob màu nằm gần với minDistBetweenBlobs được hợp nhất.
− Tính toán tâm và bán kính (Center & Radius Calculation): Các tâm và bán kính của
các blob màu mới được hợp nhất để tính toán và trả về cho phép lập.
c. Lọc Blobs theo màu sắc, kích thước và hình dạng

Các tham số cho SimpleBlobDetector có thể được thay đổi để lọc loại các blob mà chúng
ta muốn loại chúng.
− Theo màu sắc (Color): (Chú ý: đặc tính này thường dễ bị lỗi logic). Trước tiên, ta cần
đặt tham số filterByArea = 1. Đặt blobColor = 0 để chọn các blob tối và
blobColor = 255 cho các blob sáng hơn.
− Theo kích cỡ (Size): Chúng ta có thể lọc các blob màu dựa trên kích thước bằng cách
đặt tham số filterByArea = 1 và các giá trị phù hợp cho minArea và maxArea. Ví dụ:
đặt minArea = 100 sẽ lọc ra tất cả các blob màu có ít hơn 100 pixel.
− Theo hình dạng (Shape): Bây giờ hình dạng có ba tham số khác nhau.
+ Circularity: Điều này chỉ đo giá trị gần với vòng tròn của blob. Ví dụ một hình
lục giác đều có circularity lớn hơn hình vuông. Để lọc theo độ tròn, ta đặt
filterByCircularity =1. Sau đó, đặt các giá trị phù hợp cho minCircularity
và maxCircularity. Circularity được định nghĩa là
4𝜋𝐴𝑟𝑒𝑎
𝐶𝑖𝑟𝑢𝑙𝑎𝑟𝑖𝑡𝑦 =
(𝑃𝑒𝑟𝑖𝑚𝑒𝑡𝑒𝑟)2
Điều này có nghĩa là một hình tròn có circularity là 1, còn circularity của hình vuông là
0,785,…
+ Convexity: Convexity được định nghĩa là (Diện tích của Blob/diện tích của vùng
convex hull). Vùng Convex Hull có hình dạng là dạng lồi kép kín. Để lọc theo
convexity, ta đặt filterByConvexity = 1 , sau đó đặt 0 ≤ minConvexity ≤1
và maxConvexity (≤1)

Hình 3.2: Ảnh Comvexity


54
+ Inertia Ratio: Để đo lường hình dạng kéo dài như thế nào. Ví dụ: đối với hình
tròn, giá trị này là 1, đối với hình elip nằm trong khoảng từ 0 đến 1 và đối với
đường thẳng là 0. Để lọc theo Inertia Ratio, ta đặt filterByInertia = 1 và
0≤ minInertiaRatio ≤ 1 và maxInertiaRatio (≤ 1)

Hình 3.3: Ảnh Inertia ratio


3.2.2. Thuật toán xác định trọng tâm blob trên ảnh

− Hàm sử dụng
retval=cv.SimpleBlobDetector_create([, parameters])
− Code mẫu
Sinh viên chạy code này và tìm hiểu từng câu lệnh để tìm hiểu thuật toán chú ý hàm
cv2.SimpleBlobDetector_create()

import cv2
import numpy as np;
im = cv2.imread('MyPictures/blob_detection.jpg', cv2.IMREAD_GRAYSCALE)
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
detector = cv2.SimpleBlobDetector()
else :
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(im)
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]),
(0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow("Keypoints", im_with_keypoints)

cv2.waitKey(0)

3.2.3. Thuật toán xác định trọng tâm và đường bao blob trên ảnh
55
Code mẫu: Sinh viên chạy code này và tìm hiểu từng câu lệnh để tìm hiểu thuật toán chú
ý hàm cv2.SimpleBlobDetector_create()
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("MyPictures/circle.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,0)
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
M = cv2.moments(thresh)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cv2.circle(img, (cX, cY), 5, (0, 0, 255), -1)
cv2.drawContours(img, contours, 1, (0, 0, 255), 3)
cv2.putText(img, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 255, 255), 2)
cv2.imshow("Image", img)
cv2.waitKey(0)

3.2.4. Bài tập mở rộng

− Viết chương trình phát hiện các blob trên ảnh theo 2 kết quả như gợi ý (chú ý 2 kết
quả này có kết quả phát hiện blob là khác nhau)

− Viết chương trình tìm hình như kết quả gợi ý (chú ý kết quả được là các đường bao
và tên của 5 hình dạng đơn giản)

56
3.3. Phát hiên đối tượng dùng biến đổi Hough

3.3.1. Phát hiện đường thẳng dùng phương pháp houghline

Biến đổi Hough là một phương pháp được sử dụng trong xử lý ảnh để phát hiện bất kỳ
hình dạng nào trên ảnh, nếu hình dạng được biểu diễn dưới dạng toán học. Nó còn phát hiện
hình dạng ngay cả khi nó bị hỏng hoặc biến dạng.
Chúng ta sẽ tìm hiểu nguyên tắt hoạt động của biến đổi Hough để phát hiện đường thẳng
bằng hàm HoughLine. Để áp dụng phương pháp Houghline, trước tiên ta phải thực hiện dò biên
của ảnh.
3.3.2. Khái niệm cơ bản về phương pháp Houghline

Một đường thẳng có thể được biểu diễn dưới dạng y = mx + c hoặc ở dạng tham số, r =
xcosθ + ysinθ trong đó r là khoảng cách vuông góc từ gốc đến đường và θ là góc được tạo bởi
đường vuông góc này và trục hoành được tính theo chiều kim đồng hồ (Hướng này có thể thay
đổi tùy theo cách biểu diễn hệ tọa độ được sử dụng trong OpenCV).

Hình 3.4: Biến đổi Houghline


Vì vậy, bất kỳ đường thẳng nào cũng có thể được biểu diễn trong hai đại lượng (r, θ).
3.3.3. Hoạt động của phương pháp Houghline

− Đầu tiên nó được tạo ra một mảng 2D hoặc bộ tích lũy để giữ các giá trị của hai tham
số và ban đầu nó được đặt tại 0.
− Đặt các hàng biểu diễn cho r và các cột biểu diễn θ.
− Kích thước của mảng phụ thuộc vào độ chính xác chúng ta cần. Giả sử ta muốn độ
chính xác của các góc là 1 độ, sẽ cần 180 cột (Góc tối đa cho một đường thẳng là 180
độ).
57
− Đối với r chính là khoảng cách tối đa là chiều dài đường chéo của ảnh. Vì vậy khi lấy
được một pixel chính xác, số lượng hàng chính là chiều dài đường chéo của hình ảnh.
3.3.4. Thí dụ về biến đổi Hough

Xem xét ảnh có kích thước 100×100 với một đường ngang ở giữa. Lấy điểm đầu tiên của
đường. Ta biết giá trị tọa độ (x, y) của nó. Trong phương trình đường thẳng, đặt các giá trị θ =
0,1,2, …, 180 và kiểm tra r nhận được. Với mỗi cặp (r, 0), ta tăng giá trị lên một trong bộ tích
lũy trong các ô (r, 0) tương ứng của nó. Nên hiện tại trong bộ tích lũy ô (50,90) = 1 cùng với
một số ô khác.
Bây giờ lấy điểm thứ hai trên đường thẳng, làm tương tự như trên. Tăng các giá trị trong
các ô tương ứng với (r, 0) lần này ta có ô (50,90) = 2. Chúng ta thực sự đang cộng dồn các giá
trị (r, 0). Ta tiếp tục quá trình này cho mọi điểm trên dòng. Tại mỗi điểm ô (50,90) sẽ được tăng
hoặc cộng dồn, trong khi các ô khác có thể không được cộng dồn. Bằng cách này đến cuối ô
(50,90) sẽ có giá trị cộng dồn tối đa. Vì vậy, nếu muốn tìm kiếm bộ tích lũy cho giá trị cộng
dồn tối đa, ta sẽ nhận được giá trị (50,90), khi đó có một dòng trong ảnh này ở khoảng cách 50
từ gốc và ở góc là 90 độ.

Hình 3.5: Kết quả của ví dụ biến đổi Hough


Mọi thứ được giải thích ở trên được thực hiện trong hàm OpenCV cv2.HoughLine. Nó
chỉ đơn giản là trả về một mảng các giá trị (r, 0), r được đo bằng pixel và 0 được đo bằng radian.
3.3.5. Các ứng dụng của biến đổi Hough

− Biến đổi Hough được sử dụng tách các đặc trưng theo hình dạng cụ thể trên.
− Tìm sai lệch giữa các khoảng trống trong mô tả đặc trưng đường bao và không chịu
ảnh hưởng bởi nhiễu trên ảnh.
− Được sử dụng rộng rãi trong quét mã vạch, kiểm tra và nhận dạng
− Code mẫu biến đổi HoughLinesP: Sinh viên chạy các code này và tìm hiểu từng câu
lệnh

58
3.3.6. Thuật toán biến đổi Hough

− Hàm sử dụng
lines=cv.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]])
lines=cv.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
circles=cv.HoughCircl(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[,
maxRadius]]]]])

− Code mẫu
Sinh viên chạy code này và tìm hiểu từng câu lệnh để tìm hiểu thuật toán chú ý hàm
cv2.HoughLinesP()

import cv2
import numpy as np
img = cv2.imread('MyPictures/lines.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 75, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, maxLineGap=250)
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 3)
cv2.imshow("Edges", edges)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.3.7. Bài tập mở rộng

− Viết chương trình sử dụng biến đổi HoughLines để tìm đường trong ảnh có kết quả
như gợi ý

− Viết chương trình sử dụng biến đổi HoughLinesP và hàm thống kê để tìm đường trong
ảnh có kết quả như gợi ý

59
3.4. Khôi phục ảnh

3.4.1. Khôi phục ảnh bằng cách khử nhiễu

a. Giới thiệu

Trong các chương trước, chúng ta đã thấy nhiều kỹ thuật làm mịn hình ảnh như Gaussian
Blurring, Median Blurring, v.v. và chúng rất tốt trong một chừng mực nào đó trong việc loại bỏ
một lượng nhiễu nhỏ. Trong các kỹ thuật đó, chúng ta đã lấy một vùng lân cận nhỏ xung quanh
một pixel và thực hiện một số thao tác như trung bình trọng số gaussian, trung vị của các giá
trị, v.v. để thay thế phần tử trung tâm. Nói tóm lại, loại bỏ nhiễu của một pixel đối với vùng lân
cận của nó gọi là phương pháp cục bộ.
Còn đối với đặc tình của nhiễu. Nhiễu thường được coi là một biến ngẫu nhiên với giá trị
trung bình bằng không. Hãy xét một pixel nhiễu, (p = p0 + n) trong đó p0 là giá trị thực của
pixel và n là nhiễu của pixel đó. Ta có thể lấy số lượng lớn các pixel giống nhau (giả sử N) từ
các ảnh khác nhau và tính trung bình của chúng. Tốt nhất, ta nên lấy (p = p0) vì nhiễu có giá trị
trung bình bằng không.
Chúng ta có thể tự xác định chúng bằng cách đơn giản. Giữ cố định camera đến một vị trí
nhất định trong vài giây. Điều này chúng sẽ cung cấp cho ta nhiều khung hình, hoặc rất nhiều
ảnh của cùng một cảnh quan. Sau đó viết một đoạn code để tìm mức trung bình của tất cả các
khung trong video. So sánh kết quả cuối cùng với khung đầu tiên. Ta có thể thấy giảm
nhiễu. Nhưng phương pháp đơn giản này không đáp ứng đối với chuyển động của máy ảnh và
cảnh quan. Ngoài ra thường chỉ có một hình ảnh nhiễu có sẵn.
Vì vậy, ý tưởng rất đơn giản là chúng ta cần một tập hợp các ảnh tương tự nhau để giảm
nhiễu. Ta sử dụng một cửa sổ nhỏ (giả sử cửa sổ 5x5) cho ảnh. Thách thức lớn là các mẫu giống
nhau có thể ở một nơi khác trong ảnh. Đôi khi trong một vùng lân cận nhỏ xung quanh nó. Việc
sử dụng các mẫu giống nhau này được tính toán để tìm trị trung bình của chúng, kết quả sẽ tốt
nhất cho từng cửa sổ cụ thể. Xem hình ảnh ví dụ dưới đây:

Hình 3.6: Ảnh ví dụ nhiễu

60
Các mảng trong khung màu xanh dương và màu xanh lá trên ảnh là trông giống nhau. Vì
vậy, chúng ta lấy một pixel từ một cửa sổ xung quanh nó, sau đó tìm các cửa sổ tương tự trong
ảnh, sau đó lấy trung bình tất cả các cửa sổ và thay thế pixel bằng kết quả mà chúng vừa tính
được. Phương pháp này là phương pháp khử nhiễu toàn cục. Phải mất nhiều thời gian hơn so
với các kỹ thuật làm mờ mà chúng ta đã thấy trước đó, nhưng kết quả của nó tốt hơn.
b. Khử nhiễu hình ảnh trong OpenCV

OpenCV cung cấp bốn cách cho kỹ thuật này

− cv.fastNlMeansDenoising () – Sử dụng với ảnh xám.


− cv.fastNlMeansDenoisingColored () - Sử dụng với hình ảnh màu.
− cv.fastNlMeansDenoisingMulti () - Sử dụng với chuỗi ảnh được chụp trong khoảng
thời gian ngắn (ảnh thang xám).
− cv.fastNlMeansDenoisingColoredMulti () - Sử dụng với chuỗi ảnh được chụp trong
khoảng thời gian ngắn (ảnh màu).

dst=cv.fastNlMeansDenoising(src, h[, dst[, templateWindowSize[, searchWindowSize[,


normType]]]])
dst=cv.fastNlMeansDenoisingColored(src[, dst[, h[, hColor[, templateWindowSize[,
searchWindowSize]]]]])
Các đối số phổ biến là:
− h: tham số quyết định cường độ bộ lọc. Giá trị h cao hơn sẽ loại bỏ nhiễu tốt hơn,
nhưng cũng loại bỏ các chi tiết của hình ảnh. (khuyên dùng 10)
− hForColorComponents: giống như h, nhưng chỉ dành cho hình ảnh màu.
− templateWindowSize: nên là số lẻ. (khuyên dùng 7)
− searchWindowSize: nên là số lẻ. (khuyên dùng 21)
c. Code mẫu

Sinh viên chạy code này và tìm hiểu từng câu lệnh để tìm hiểu hàm khử nhiễu
− Ví dụ trường hợp sử dụng hàm cv.fastNlMeansDenoisingColored ()
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('C:/BAI TAP PYTHON/DATA_HINH/die.png')


dst = cv.fastNlMeansDenoisingColored(img,None,10,10,7,21)
plt.subplot(121),plt.imshow(img)
plt.subplot(122),plt.imshow(dst)
plt.show()

− Ví dụ trường hợp sử dụng hàm cv.fastNlMeansDenoisingMulti ()


import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
cap = cv.VideoCapture('C:/BAI TAP PYTHON/Myvideo/vtest.avi')
61
img = [cap.read()[1] for i in range(5)]
gray = [cv.cvtColor(i, cv.COLOR_BGR2GRAY) for i in img]
gray = [np.float64(i) for i in gray]
noise = np.random.randn(*gray[1].shape)*10
noisy = [i+noise for i in gray]
noisy = [np.uint8(np.clip(i,0,255)) for i in noisy]
dst = cv.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)
plt.subplot(131),plt.imshow(gray[2],'gray')
plt.subplot(132),plt.imshow(noisy[2],'gray')
plt.subplot(133),plt.imshow(dst,'gray')
plt.show()
d. Bài tập mở rộng

− Viết chương trình khử nhiễu ảnh sử dụng hàm sau


cv.fastNlMeansDenoising ()
cv.fastNlMeansDenoisingColoredMulti ()

3.4.2. Kỹ thuật khôi phục ảnh Inpainting

a. Khái niệm cơ bản

Hầu hết các ảnh cũ xuống cấp được cất giữ lâu ngày sẽ có một số đốm đen, một số đường
nét trên đó. Chúng ta không thể đơn giản xóa chúng trong một công cụ bình thường như sơn
lên nó được bởi vì nó sẽ thay thế các cấu trúc màu đen bằng các cấu trúc màu trắng không phù
hợp. Trong những trường hợp này, một kỹ thuật gọi là inpainting ảnh được sử dụng. Ý tưởng
cơ bản rất đơn giản: Thay thế những dấu vết đó bằng các pixel lân cận của nó để nó trông giống
như vùng lân cận. Hãy xem xét hình ảnh hiển thị

Hình 3.7: Kết quả của ví dụ nhiễu sử dụng inpainting


Một số thuật toán được thiết kế cho mục đích này và OpenCV cung cấp hai trong số
chúng. Cả hai có thể được truy cập bởi cùng một hàm, cv2.inpaint ()
dst=cv.inpaint(src, inpaintMask, inpaintRadius, flags[, dst])

Thuật toán này được kích hoạt bằng cách sử dụng flags, cv2.INPAINT_TELEA,
cv2.INPAINT_NS
b. Bài tập mở rộng

Viết chương trình khử nhiễu ảnh sử dụng hàm sau


dst=cv.inpaint(src, inpaintMask, inpaintRadius, flags[, dst])

62
3.4.3. Khôi phục ảnh HDR (High Dynamic Range)

a. Khái niệm cơ bản

Ảnh dải động cao (HDRI hoặc HDR) là một kỹ thuật được sử dụng trong thu nhận ảnh
và nhiếp ảnh để tái tạo dải sáng động lớn hơn so với kỹ thuật chụp ảnh kỹ thuật số hoặc hình
ảnh chuẩn. Mặc dù mắt người có thể điều chỉnh trong một dải các điều kiện ánh sáng, hầu hết
các thiết bị hình ảnh đều sử dụng 8 bit trên mỗi kênh, vì vậy chúng ta chỉ giới hạn đến 256
mức. Khi chúng ta chụp ảnh cảnh thế giới thực, các vùng sáng có thể bị tăng sáng quá mức,
trong khi vùng tối có thể bị thiếu sáng, vì vậy chúng ta không thể chụp được tất cả các chi tiết
bằng một lần tăng sáng. Ảnh HDR hoạt động với hình ảnh sử dụng nhiều hơn 8 bit trên mỗi
kênh (thường là giá trị float 32 bit), cho phép phạm vi động rộng hơn.
Có nhiều cách khác nhau để có được hình ảnh HDR, nhưng cách phổ biến nhất là sử dụng
ảnh chụp cảnh được chụp với các giá trị tăng độ sáng khác nhau. Khi kết hợp các mức tăng độ
sáng này nó rất hữu ích khi ta biết đặc tính phản hồi của máy ảnh và có các thuật toán để ước
tính điều này. Sau khi ảnh HDR được tổng hợp, chúng phải được chuyển đổi trở lại thành 8 bit
để quan sát nó trên màn hình thông thường. Quá trình này được gọi là tonemicking. Sự phức
tạp sẽ phát sinh khi các đối tượng của cảnh hoặc máy ảnh di chuyển giữa các bức ảnh, vì các
hình ảnh có độ tăng sáng khác nhau phải được căn chỉnh.
Trong nội dung này chúng ta thực hiện 2 thuật toán (Debvec, Robertson) để tạo và hiển
thị ảnh HDR từ chuỗi tăng độ sáng và trình bày một phương pháp thay thế gọi là phản ứng tổng
hợp tăng độ sáng (Mertens) để tạo ra ảnh dải động thấp và không cần dữ liệu thời gian tăng độ
sáng. Hơn nữa, chúng ta có thể ước tính chức năng phản hồi của máy ảnh (CRF) có giá trị lớn
đối với nhiều thuật toán thị giác máy tính. Mỗi bước thực hiện cho ảnh HDR có thể được thực
hiện bằng các thuật toán và tham số khác nhau, vì vậy hãy xem hướng dẫn tham khảo để xem
tất cả.
b. Các hàm sử dụng

cv2.createMergeDebevec()

cv2.createMergeRobertson()

cv2.createTonemapDurand()

cv2.createMergeMertens()

c. Bài tập mở rộng

Viết chương khôi phục ảnh HDR sử dụng hàm sau


cv.createMergeDebevec()
cv.createMergeRobertson()

63
cv.createTonemapDurand()
cv.createMergeMertens()

3.5. Bài tập áp dụng

a. Áp dụng biến đổi Hough

− Viết chương trình tìm đường thẳng từ hình ảnh trên camera sử dụng biến đổi
Hough theo thời gian thực sử dụng hàm HoughLinesP
− Viết chương trình tìm đường tròn từ hình ảnh trên camera sử dụng biến đổi Hough
theo thời gian thực sử dụng hàm HoughCircles
− Viết chương trình tìm đường tròn từ hình ảnh và in ra tọa độ tâm, bán kính của
từng hình tròn tìm được.
− Viết chương trình tìm các blob từ hình ảnh trên camera theo thời gian thực sử
dụng hàm tìm và vẽ đường tròn
− Viết chương trình tìm các blob từ hình ảnh trên camera theo thời gian thực sử
dụng hàm cv2.SimpleBlobDetector_create()

− Viết chương trình ứng dụng xác định các con cờ hình tròn trên bàn cờ có kết quả
như gợi ý

b. Viết chương trình chuẩn hóa camera

− Viết chương trình sử dụng hàm cv2.findChessboardCorners() cho 2 ảnh board


− Viết chương trình sử dụng hàm cv2.findCirclesGrid() cho 2 ảnh circle
c. Các bài tập nâng cao

− Viết chương trình xác định vùng của mắt sử dụng biến đổi HoughCircles có kết
quả như gợi ý

64
− Viết chương trình dò lines trên video sử dụng biến đổi Hough có kết quả như gợi ý

− Viết chương trình trên ảnh dùng mặt nạ theo đường bao và màu có kết quả như gợi ý

65

You might also like