Computer Vision

[Image Descriptor] Hu Moments

Xin chào, trong bài viết này chúng ta sẽ tìm hiểu về Hu Moments Image Descriptor và các ứng dụng của nó.


HU MOMENTS LÀ GÌ?

Hu Moments là một Image Descriptor sử dụng các phép thống kê để mô tả hình dạng của một đối tượng có trong bức ảnh nhị phân hoặc edged-image.

Hu Moments Image Descriptor trả về một Feature Vector gồm 7 giá trị. Feature Vector này sẽ được so sánh với nhau để xác định sự tương đồng giữa hai vật thể.


HU MOMENTS TRONG OPENCV

Để tính toán các giá trị của Hu Moments, OpenCV cung cấp function cv2.HuMoments()

moments = cv2.HuMoments(cv2.moments(roi))

Trong đó:

  • moments – Feature Vector nhận được từ function cv2.HuMoments();
  • cv2.moments() – function dùng để tính các giá trị moment của đối tượng.

Example 1:

import cv2
import imutils
import numpy as np

image = cv2.imread("humoments_planes.png")
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]

for (i, c) in enumerate(cnts):
	(x,y,w,h) = cv2.boundingRect(c)
	roi = image[y:y+h, x:x+w]
	moments = cv2.HuMoments(cv2.moments(roi)).flatten()

	print "MOMENTS #{}: {}".format(i+1, moments)
	cv2.imshow("ROI #{}".format(i+1), roi)
	cv2.waitKey(0)

Input:
humoments_planes
Output:
MOMENTS #1: […]
MOMENTS #2: […]
MOMENTS #3: […]

Giải thích:

Để sử dụng Hu Moments hiệu quả, chúng ta cần áp dụng function cv2.HuMoments() cho từng đối tượng cụ thể.


PHÂN BIỆT ĐỐI TƯỢNG VỚI HU MOMENTS

Bây giờ chúng ta sẽ thực hiện một project nho nhỏ, phân biệt hình dạng của các đối tượng từ một tập hợp rất lớn.

Đầu tiên chúng ta cần tạo một dataset gồm 500 bức ảnh chứa các hình tròn có đường kính khác nhau.

Source code: dataGenerator.py

import cv2
import uuid
import numpy as np
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", required=True)
ap.add_argument("-n", "--amount", type=int, default=500)

args = vars(ap.parse_args())

for i in range(0, args["amount"]):
	image = np.zeros((500,500,3), dtype="uint8")
	(x,y) = np.random.randint(low=100,high=400,size=2)
	r = np.random.randint(low=25,high=100)
	color = np.random.randint(low=0,high=255,size=3)
	color = tuple(map(int,color))

	cv2.circle(image, (x,y), r, color, -1)
	cv2.imwrite("{}/{}.jpg".format(args["output"], uuid.uuid4()), image)

image = np.zeros((500,500,3), dtype="uint8")
topLeft = tuple(np.random.randint(low=25,high=225,size=2))
botRight = tuple(np.random.randint(low=250,high=400,size=2))
color = np.random.randint(low=0,high=255,size=3)
color = tuple(map(int,color))

cv2.rectangle(image, topLeft, botRight, color, -1)
cv2.imwrite("{}/{}.jpg".format(args["output"], uuid.uuid4()), image)

Execution:
$ python dataGenerator.py -o dataset 

Output:

dataset

Sau khi chạy đoạn code trên thì trong folder dataset sẽ xuất hiện 501 bức ảnh chứa các hình tròn với màu sắc và kích thước khác nhau.

Bây giờ chúng ta sẽ áp dụng Hu Moments để tìm ra bức ảnh duy nhất có chứa hình vuông trong dataset.

Source code: findRect.py

from sklearn.metrics.pairwise import pairwise_distances
import cv2
import numpy as np
import argparse
import glob
import imutils

ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True)
args = vars(ap.parse_args())

imagePaths = sorted(glob.glob(args["dataset"]+"/*.jpg"))
data = []

for imagePath in imagePaths:
	image = cv2.imread(imagePath)
	gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
	thresh = cv2.threshold(gray, 5, 255, cv2.THRESH_BINARY)[1]

	cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
	c = max(cnts, key=cv2.contourArea)

	(x,y,w,h) = cv2.boundingRect(c)
	roi = cv2.resize(thresh[y:y+h,x:x+w], (50,50))
	moments = cv2.HuMoments(cv2.moments(roi)).flatten()
	data.append(moments)

D = pairwise_distances(data).sum(axis=0)
i = np.argmax(D)

image = cv2.imread(imagePaths[i])
print("Found square: {}".format(imagePaths[i]))
cv2.imshow("Outlier", image)
cv2.waitKey(0)

Giải thích:
– Dòng 1: để so sánh các Feature Vector với nhau, chúng ta cần import method pairwise_distances từ package sklearn.metrics.pairwise. Như chúng ta đã biết, các đối tượng có hình dạng càng giống nhau thì distance giữa các Feature Vector càng nhỏ;
– Dòng 15-26: sau khi áp dụng threshold(), findContours() và boundingRect(), chúng ta nhận được Range Of Image tương ứng với từng đối tượng. Tuy nhiên các đối tượng này có kích thước khác nhau, do đó BẮT BUỘC chúng ta cần chuyển tất cả các ROI này về một kích thước đồng nhất, để Feature Vector nhận được không bị ảnh hưởng bởi kích thước của đối tượng;
– Dòng 28, 29: method pairwise_distances() được dùng để tính toán distance giữa từng Feature Vector. Kết quả trả về là một ma trận NxN entries chứa distance giữa N Vector. Sau đó chúng ta tính tổng các distance theo một trục bất kỳ (vì đây là ma trận đối xứng) và tìm ra index của giá trị lớn nhất. Đây cũng chính là index của bức ảnh chứa hình chữ nhật trong imagePaths.

Output:

rect

Như vậy chúng ta đã tìm ra được bức ảnh duy nhất trong dataset có chứa hình chữ nhật. Tất nhiên, một vấn đề luôn có nhiều giải pháp, ngoài cách sử dung Hu Moments, chúng ta cũng có thể sử dụng Contour Properties.


SUGGESTIONS

Nếu có nhiều đối tượng trong bức ảnh, chúng ta phải tách và áp dụng Hu Moments cho từng đối tượng riêng biệt. Ngược lại, chúng ta chỉ cần nhị phân hóa bức ảnh và áp dụng Hu Moments.

Ưu điểm của Hu Moments:

  • Thời gian tính toán nhanh;
  • Kích thước nhỏ;
  • Mô tả tốt các hình dạng đơn giản;
  • Không có tham số.
  • Không bị ảnh hưởng bởi các thay đổi về rotation, reflection và scale.
  • Translation invariance is obtained by using a tight cropping of the object to be described.

Nhược điểm:

  • Yêu cầu nhị phân hóa đối tượng một cách chính xác, điều này thường rất khó trong điều kiện thực tế.
  • Thường chỉ được áp dụng cho các hình 2D đơn giản.
  • Hu Moment calculations are based on the initial centroid computation — if the initial centroid cannot be repeated for similar shapes, then Hu Moments will not obtain good matching accuracy.

SUMMARY

Như vậy chúng ta đã tìm hiểu về Hu Moments, cách áp dụng và ưu/nhược điểm có nó. Cảm ơn các bạn đã theo dõi bài viết.

Thân ái và quyết thắng.

Reference:
[1] OpenCV Shape Descriptor – Hu Moments.

One thought on “[Image Descriptor] Hu Moments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s