Tâm của 1 hình đại diện toạ độ cho toàn trong xử lý ảnh, ngoài các đặc tính là vị trí tâm hình còn có các đặc tính như diện tích, hướng của hình,
Làm thế nào để tìm tâm của 1 hình, đối với các hình đối xứng có quy luật thì việc tìm tâm khá dễ dàng như tìm tâm hình vuông, elip, hình tròn, chữ nhật… nhưng với các hình bất kỳ thì làm như thế nào?
Trọng tâm của một hình dạng là trung bình cộng (tức là trung bình cộng) của tất cả các điểm trong một hình dạng.
Giả sử một hình dạng bao gồm điểm khác biệt , sau đó centroid(Trọng tâm) được cung cấp bởi
Image moment là gì. Image Moment là giá trị trung bình thuộc tính của hình, có thể tìm thấy một số thuộc tính cụ thể của hình như bán kính, diện tích, tâm, v.v. Để tìm tâm của hình ảnh, thường chuyển đổi hình sang định dạng nhị phân và sau đó tìm trung tâm của hình.
Centroid(trọng tâm) được cho bởi công thức: –
là tọa độ x và là tọa độ y của tâm và biểu thị moment, tham khảo trang https://learnopencv.com/find-center-of-blob-centroid-using-opencv-cpp-python/ về cách tính trọng tâm hình
copy ảnh sau vào project:
các bước thực hiện :
- Chuyển đổi sang thang độ xám.
- Làm mờ để giảm nhiễu tần số cao để làm cho quá trình phát hiện đường viền của chúng tôi chính xác hơn.
- Binarization – chuyển đổi ảnh nhị phân chỉ có trắng đen kiểu đảo ngược của hình ảnh. Thông thường, phát hiện cạnh và ngưỡng được sử dụng cho quá trình này. Trong bài này sẽ áp dụng ngưỡng.
ta có code sau:
1 2 3 4 5 6 7 8 9 10 11 |
<strong><span style="color: #993300;"># Thêm thư viện cần thiết</span></strong> <strong><span style="color: #993300;">import imutils</span></strong> <strong><span style="color: #993300;">import cv2</span></strong> <strong><span style="color: #993300;"># đọc ảnh</span></strong> <strong><span style="color: #993300;">image = cv2.imread("hinh1.png")</span></strong> <strong><span style="color: #993300;"># Biến đổi ảnh thành ảnh đen trắng theo thang độ xám</span></strong> <strong><span style="color: #993300;">gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)</span></strong> <strong><span style="color: #993300;"># Làm mờ, mịn ảnh chống nhiễu tần số cao</span></strong> <strong><span style="color: #993300;">blurred = cv2.GaussianBlur(gray, (3, 3), 0)</span></strong> <strong><span style="color: #993300;"># Tiến hành lọc ngưỡng threshold Binary kiểu đảo ngược bit</span></strong> <strong><span style="color: #993300;">thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY_INV)[1]</span></strong> |
kết quả:
Lưu ý: sử dụng lọc ngưỡng nhị phân kiểu đảo ngược (cv2.THRESH_BINARY_INV) bit để được ảnh với hình màu trắng nền màu đen để quá trình tìm đường viền chạy đúng.
Tiếp theo tiến hành tìm đường viền bao quanh , mỗi 1 đường viền bao được tìm thấy tiến hành tính toán trọng tâm của hình. Ta có code sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<strong><span style="color: #993300;"># tìm đường viền của hình trong ảnh threshold</span></strong> <strong><span style="color: #993300;">cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,</span></strong> <strong><span style="color: #993300;"> cv2.CHAIN_APPROX_SIMPLE)</span></strong> <strong><span style="color: #993300;"># Đếm số đường viền khép kín tìm được</span></strong> <strong><span style="color: #993300;">cnts = imutils.grab_contours(cnts)</span></strong> <strong><span style="color: #993300;"># Vòng lặp áp dụng cho các đường viền tìm được</span></strong> <strong><span style="color: #993300;">for c in cnts:</span></strong> <strong><span style="color: #993300;"> # tính toán tâm của đường viền bao quanh hình</span></strong> <strong><span style="color: #993300;"> #</span></strong> <strong><span style="color: #993300;"> M = cv2.moments(c)</span></strong> <strong><span style="color: #993300;"> cX = int(M["m10"] / M["m00"])</span></strong> <strong><span style="color: #993300;"> cY = int(M["m01"] / M["m00"])</span></strong> <strong><span style="color: #993300;"> # Vẽ đường bao và tâm của hình</span></strong> <strong><span style="color: #993300;"> # Vẽ đường bao quanh</span></strong> <strong><span style="color: #993300;"> cv2.drawContours(image, [c], -1, (0, 255, 0), 2)</span></strong> <strong><span style="color: #993300;"> # vẽ tâm</span></strong> <strong><span style="color: #993300;"> cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)</span></strong> <strong><span style="color: #993300;"> #Hiển thi toa độ tâm</span></strong> <strong><span style="color: #993300;"> cv2.putText(image, "x={0},y={1}".format(cX,cY), (cX - 40, cY - 20),</span></strong> <strong><span style="color: #993300;"> cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)</span></strong> <strong><span style="color: #993300;"> # hiển thị ảnh sau khi xử lý</span></strong> <strong><span style="color: #993300;"> cv2.imshow("Image", image)</span></strong> <strong><span style="color: #993300;"> cv2.imshow("thresh", thresh)</span></strong> <strong><span style="color: #993300;"> cv2.waitKey(0)</span></strong> |
kết quả :
toàn bộ code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<strong><span style="color: #993300;"># Thêm thư viện cần thiết</span></strong> <strong><span style="color: #993300;">import imutils</span></strong> <strong><span style="color: #993300;">import cv2</span></strong> <strong><span style="color: #993300;"># đọc ảnh</span></strong> <strong><span style="color: #993300;">image = cv2.imread("hinh2.png")</span></strong> <strong><span style="color: #993300;"># Biến đổi ảnh thành ảnh đen trắng theo thang độ xám</span></strong> <strong><span style="color: #993300;">gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)</span></strong> <strong><span style="color: #993300;"># Làm mờ, mịn ảnh chống nhiễu tần số cao</span></strong> <strong><span style="color: #993300;">blurred = cv2.GaussianBlur(gray, (3, 3), 0)</span></strong> <strong><span style="color: #993300;"># Tiến hành lọc ngưỡng threshold Binary kiểu đảo ngược bit</span></strong> <strong><span style="color: #993300;">thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY_INV)[1]</span></strong> <strong><span style="color: #993300;"># tìm đường viền của hình trong ảnh threshold</span></strong> <strong><span style="color: #993300;">cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,</span></strong> <strong><span style="color: #993300;"> cv2.CHAIN_APPROX_SIMPLE)</span></strong> <strong><span style="color: #993300;"># Đếm số đường viền khép kín tìm được</span></strong> <strong><span style="color: #993300;">cnts = imutils.grab_contours(cnts)</span></strong> <strong><span style="color: #993300;"># Vòng lặp áp dụng cho các đường viền tìm được</span></strong> <strong><span style="color: #993300;">for c in cnts:</span></strong> <strong><span style="color: #993300;"> # tính toán tâm của đường viền bao quanh hình</span></strong> <strong><span style="color: #993300;"> #</span></strong> <strong><span style="color: #993300;"> M = cv2.moments(c)</span></strong> <strong><span style="color: #993300;"> cX = int(M["m10"] / M["m00"])</span></strong> <strong><span style="color: #993300;"> cY = int(M["m01"] / M["m00"])</span></strong> <strong><span style="color: #993300;"> # Vẽ đường bao và tâm của hình</span></strong> <strong><span style="color: #993300;"> # Vẽ đường bao quanh</span></strong> <strong><span style="color: #993300;"> cv2.drawContours(image, [c], -1, (0, 255, 0), 2)</span></strong> <strong><span style="color: #993300;"> # vẽ tâm</span></strong> <strong><span style="color: #993300;"> cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)</span></strong> <strong><span style="color: #993300;"> #Hiển thi toa độ tâm</span></strong> <strong><span style="color: #993300;"> cv2.putText(image, "x={0},y={1}".format(cX,cY), (cX - 40, cY - 20),</span></strong> <strong><span style="color: #993300;"> cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)</span></strong> <strong><span style="color: #993300;"> # hiển thị ảnh sau khi xử lý</span></strong> <strong><span style="color: #993300;"> cv2.imshow("Image", image)</span></strong> <strong><span style="color: #993300;"> cv2.imshow("thresh", thresh)</span></strong> <strong><span style="color: #993300;"> cv2.waitKey(0)</span></strong> |
Dựa vào tâm của vật ta tính được vị trí của vật so với vị trí gốc quy định, phục vụ cho bài toán xác định trí vật sau này.