Histogram of oriented gradients là gì

     
Kiến thức nền tảngHistogramSliding windowsConvolutionĐạo hàm hình ảnh (image gradient)Giới thiệu HOG - Histograms of Oriented Gradients

Phương pháp rút trích đặc trưng hình hình ảnh HOG xuất phiên bản ở hội nghị CVPR 2005 được khuyến nghị bởi người sáng tác là Dalal và Triggs. Chúng ta không tưởng lầm đâu, năm 2005 đấy :D. Bài xích báo nơi bắt đầu HOG đề xuất phương pháp rút trích đặc trưng sử dụng những thống kê histogram về hướng trên hình ảnh gradient cho bài toán phát hiện bạn (human detection). CVPR là một trong những hội nghị thuộc sản phẩm đỉnh của nghành thị giác sản phẩm tính. Bởi đó, bài xích báo HOG này xuất hiện thêm ở đó quả thật là 1 trong điều gì đó không bắt buộc là ngẫu nhiên. Tuy nhiên bài toán phát hiện bạn với những phương pháp hiện đại trong học sâu đã mang lại ra kết quả tốt vượt bậc đánh bại các phương pháp truyền thống. Nhưng chưa hẳn vì vậy nhưng mình "được phép" nhảy cóc bỏ lỡ những phương pháp xử lý truyền thống, đây là quan điểm cá nhân của mình.

Bạn đang xem: Histogram of oriented gradients là gì

Link bài xích báo gốc: http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf

Rút trích đặc thù hình hình ảnh nằm ở bước nào nhằm giải bài toán phát hiện nay đối tượng? Rồi, mình sẽ nêu luồng vận động cơ bản của những giải thuật phát hiện tại đối tượng:

Đọc ảnhTiền giải pháp xử lý (preprocessing): hình ảnh được đưa qua cách tiền xử trí để triển khai các làm việc như cân đối sáng, làm cho mờ, …Trích quánh trưng hình ảnh (feature extraction): bằng cách sử dụng các phương thức rút trích quánh trưng ảnh ta sẽ thu được vector sệt trưng của ảnh. Nói một biện pháp nôm na quen thuộc đó đó là bạn mã hóa hình ảnh thành một vector, cùng vector này với những đặc trưng (các số thực) thay mặt cho ảnh đó.Huấn luyện quy mô học thiết bị (training): với phương thức truyền thống, ta thường sử dụng quy mô SVM trong machine learning nhằm phân tách bóc các vector đặc thù thành các lớp buộc phải phân loại.Kiểm thử (validation): sau khoản thời gian huấn luyện xong xuôi mô hình học tập máy bạn phải đánh giá quy mô mình đã huấn luyện đạt độ chính xác là bao nhiêu xác suất trên tập kiểm test này. Khi chúng ta đã ăn nhập với hiệu quả kiểm thử, ta rất có thể dừng quá trình huấn luyện.

Đấy!! Trích quánh trưng ảnh nằm ở bước số 2. Đặc trưng hình hình ảnh rút trích có tốt hay ko sẽ tác động đến kết quả của độ chính xác. Vì vậy, sống các cách thức truyền thống, họ đưa ra các xây dựng nhằm nỗ lực rút trích tin tức hình ảnh một cách tốt nhất.

Sau khi huấn luyện kết thúc mô hình SVM, quá trình kiểm tra (testing) sẽ chuyển đổi một chút ở bước 3 và bước 4. Ví dụ là ta dùng các trọng số của SVM đã tính toán được để thực hiện phân lớp, chứ chưa phải cần về tối ưu hóa các trọng số này như trong quy trình huấn luyện. Bước 4 là ta vẫn đánh giá công dụng dự đoán bởi định tính (xem bởi mắt coi nó phát hiện đối tượng người tiêu dùng có phải chăng không) hoặc định lượng (cân đo đong đếm % độ chủ yếu xác).

Hiện thực giải thuật HOG

*

(nguồn ảnh: bài xích báo gốc HOG)

Mình đã đi chi tiết từng bước 1 nhé. Ở mỗi bước mình vẫn minh họa những script ngắn, còn code HOG sử dụng được vẫn post nghỉ ngơi cuối nội dung bài viết này. Tại thời khắc viết code cho nội dung bài viết ngay dịp này, bản thân đang xem thêm bài báo gốc của người sáng tác để hiện nay thực. Vày vậy, mọi fan hãy nỗ lực rèn luyện những kĩ năng để hiểu hiểu paper nước ngoài nhé, tuyệt nhất là tiếng Anh cùng kiến thức gốc rễ Xử lý ảnh.

1. Chuẩn hóa mức sáng và màu sắc của ảnh

Việc dùng hình ảnh màu cùng các chuẩn chỉnh hóa trên hình ảnh cho kết quả tốt hơn ảnh xám khoảng chừng 1.5%. Thôi, ta là dân newbie bắt đầu học, cạnh tranh quóa làm lơ nhe. Đọc hình ảnh xám cho gọn dịu nè :x. Ảnh đầu vô kích thước 64x128 (w x h) pixels.


2. Tính gradient của ảnh

Có rất nhiều cách đạo hàm ảnh để tính gradient như Laplacian, Sobel. Ủa ủa, sao chữ gradient quen thừa vậy ta :D, té ra là tại chỗ này Gradient của hình ảnh là gì?. Chém chuối vậy thoai, chớ mình sử dụng filter 1-D đơn giản và dễ dàng (-1, 0, 1) để convolution tính hình ảnh đạo hàm theo trục x, và đưa vị của filter trên nhằm tính ảnh đạo hàm theo trục y.


# gradientxkernel = np.array(<<-1, 0, 1>>)ykernel = np.array(<<-1>, <0>, <1>>)dx = cv2.filter2D(img, cv2.CV_32F, xkernel)dy = cv2.filter2D(img, cv2.CV_32F, ykernel)

3. Vote hướng về phía cell (histogram)

Cái đệch! tiêu đề Vinglish vậy, ráng sao chơi :(. Cứ bình tâm nào, nhằm Minh lý giải từng chiếc một.

Xem thêm: Vpp Trong Tiếng Anh Là Gì Trong Tiếng Anh, Vpp Là Gì Trong Tiếng Anh

Ở bước 2, ta đang tính được ảnh gradient theo trục x (dx) với gradient theo trục y (dy). Kích thước dx cùng dy gần như bằng hình ảnh gốc, tức 64x128. Tưởng tượng rằng dx với dy là 2 tờ giấy hình chữ nhật gồm cùng kích thước, và chúng ta lấy 2 tờ giấy ông xã lên nhau. Bởi vậy thì mỗi px trên dx vẫn ứng cùng với 1 px ở tọa độ tương xứng trên dy. Vì vậy, cùng với cặp cực hiếm này ta công thêm được góc với biên độ tại pixel đang xét!

*

(nguồn ảnh: https://www.onlinemathlearning.com/vector-magnitude.html)

Nhìn hình ta có:

Góc (hay có thể nói là hướng) = arctan(y/x)Độ béo (biên độ) = sqrt(x * x + y * y)

Giờ trên đây ta tất cả thêm một khái niệm bắt đầu chen chân vô đó là cell (dịch: ô). Một cell có phong cách thiết kế là có size 8x8 px (đây là rất tham số, tác giả có tùy chỉnh thiết lập và lựa chọn 8 là giá chỉ trị phải chăng qua những thí nghiệm). Vày đó ảnh đầu 64x128 thì sẽ có 8x16 = 128 cell cả thảy (8 ô ngang và 16 ô dọc).

Tiếp đến, ta xét lần lượt mỗi cell. đề cập lại, một cell kích thước 8x8 vì vậy ta tất cả 64 giá trị hướng cùng 64 cực hiếm biên độ trong cell đó. Ta sẽ tiến hành vote (dịch: bầu cử) phía vào những lựa lựa chọn góc ở từ 0-180 độ (các góc quý hiếm âm sẽ được lấy trị tuyệt đối hoàn hảo quy về 0-180 luôn). Vào cung tròn 0-180 độ này, ta phân tách chúng thành những 9 đoạn rời rộc (9 bin). Giả dụ hướng nằm trong khúc như thế nào thì ta vote vào bin đó. Quá trình vote này hotline là đo lường và thống kê / những thống kê Histogram.

Cụ thể:

Hướng 0-20 độ: ta đang vote hướng thuộc đoạn này vào bin 0Hướng 20-40 độ: bin 1Hướng 40-60 độ: bin 2Hướng 60-80 độ: bin 3Hướng 80-100 độ: bin 4Hướng 100-120 độ: bin 5Hướng 120-140 độ: bin 6Hướng 140-160 độ: bin 7Hướng 160-180 độ: bin 8

Khi gồm hướng rơi vào hoàn cảnh bin, ta ko vote kiểu bình thường là giá trị trong bin tạo thêm 1 solo vị, cơ mà ta sẽ tăng lên một giá trị bởi biên độ của phía đó. Ví dụ: hướng 42 độ, biên độ 0.27 => vote vào bin 2, cực hiếm bin 2 += 0.27. Hướng của các px trong cell vote vào bin như thế nào thì giá trị bin đó tăng nhiều lên.

Sau khi vote xong, ta có 8x16 cell, từng cell tất cả 9 bin.


# histogrammagnitude = np.sqrt(np.square(dx) + np.square(dy))orientation = np.arctan(np.divide(dy, dx+0.00001)) # radianorientation = np.degrees(orientation) # -90 -> 90orientation += 90 # 0 -> 180num_cell_x = w // cell_size # 8num_cell_y = h // cell_size # 16hist_tensor = np.zeros() # 16 x 8 x 9for cx in range(num_cell_x): for cy in range(num_cell_y): ori = orientation mag = magnitude # https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html hist, _ = np.histogram(ori, bins=bins, range=(0, 180), weights=mag) # 1-D vector, 9 elements hist_tensor = hist passpass

4. Chuẩn hóa theo block

Tại sao ta cần phải chuẩn chỉnh hóa ở bước này? Vì lúc này mỗi cell đang sở hữu trong mình histogram trên vùng hình ảnh 8x8, những thông tin này mang tính chất cục bộ. Bởi vậy người sáng tác đã đưa ra nhiều cách chuẩn hóa khác nhau dựa trên các khối (block) ông xã lấn (overlap) nhau.

Đến đây ta cần biết 1 block là gì. Một block bao gồm nhiều cell, block 2x2 tức là ta có vùng diện tích s của 4 cell sát –> block này sẽ lấp trên diện tích = 16x16 pixel. Trong vượt trình chuẩn chỉnh hóa, ta đã lần lượt chuẩn chỉnh hóa block 2x2 đầu tiên, rồi dịch block đó qua 1 cell cùng cũng thực hiện chuẩn hóa đến block này. Như vậy, thân block thứ nhất và block gần kề đã có sự chồng lấn cell cho nhau (2 cell), trong giờ Anh fan ta sử dụng từ overlap.

Xem thêm: Công Thức Tính Cường Độ Điện Trường Tại Trung Điểm Hay Nhất, Cường Độ Điện Trường Tại 1 Điểm

*

(nguồn ảnh: https://www.learnopencv.com/histogram-of-oriented-gradients/)

Thao tác vắt thể chuẩn chỉnh hóa cho từng block Minh sẽ cần sử dụng L2-Norm (cho dễ hiện thực, ahihi). Giải pháp làm là bản thân lấy toàn bộ vector của 4 cell trong block đã xét nối lại cùng nhau thành vector v. Vector v bao gồm 9 x 4 = 36 phần tử. Kế tiếp ta chuẩn chỉnh hóa (tính toán lại vector v) theo công thức mặt bên dưới:

*

(nguồn ảnh: bài báo nơi bắt đầu HOG)

Bản chất của chuẩn chỉnh hóa L1-norm, L2-norm kia là:

L1-norm: sau chuẩn chỉnh hóa, tổng những giá trị của những phần tử trong vector bởi 1.L2-norm: sau chuẩn chỉnh hóa, độ lâu năm vector bởi 1.

# normalizationredundant_cell = block_size-1feature_tensor = np.zeros()for bx in range(num_cell_x-redundant_cell): # 7 for by in range(num_cell_y-redundant_cell): # 15 by_from = by by_to = by+block_size bx_from = bx bx_to = bx+block_size v = hist_tensor.flatten() # lớn 1-D array (vector) feature_tensor = v / LA.norm(v, 2)

5. Trích vector đặc trưng của những block đã chuẩn hóa cho hình ảnh 64x128

Đến đây coi như kết thúc rồi á. Block kích cỡ 2x2 chuẩn chỉnh hóa trên các block overlap, như vậy tổng số ta sẽ có 7x15 block cả thảy. Từng block mang trong bản thân 4 cell (2x2), mỗi cell có 9 bin. Tự đó, nếu như ta phẳng hóa toàn cục đặc trưng của tất cả các block bao gồm trên hình ảnh 64x128 ta sẽ được một vector đặc trưng có: 7 x 15 x 4 x 9 = 3780 phần tử!


import osimport cv2import numpy as npfrom numpy import linalg as LAIMG = "person.jpg"def hog(img_gray, cell_size=8, block_size=2, bins=9): img = img_gray h, w = img.shape # 128, 64 # gradient xkernel = np.array(<<-1, 0, 1>>) ykernel = np.array(<<-1>, <0>, <1>>) dx = cv2.filter2D(img, cv2.CV_32F, xkernel) dy = cv2.filter2D(img, cv2.CV_32F, ykernel) # histogram magnitude = np.sqrt(np.square(dx) + np.square(dy)) orientation = np.arctan(np.divide(dy, dx+0.00001)) # radian orientation = np.degrees(orientation) # -90 -> 90 orientation += 90 # 0 -> 180 num_cell_x = w // cell_size # 8 num_cell_y = h // cell_size # 16 hist_tensor = np.zeros() # 16 x 8 x 9 for cx in range(num_cell_x): for cy in range(num_cell_y): ori = orientation mag = magnitude # https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html hist, _ = np.histogram(ori, bins=bins, range=(0, 180), weights=mag) # 1-D vector, 9 elements hist_tensor = hist pass pass # normalization redundant_cell = block_size-1 feature_tensor = np.zeros() for bx in range(num_cell_x-redundant_cell): # 7 for by in range(num_cell_y-redundant_cell): # 15 by_from = by by_to = by+block_size bx_from = bx bx_to = bx+block_size v = hist_tensor.flatten() # to 1-D array (vector) feature_tensor = v / LA.norm(v, 2) # avoid NaN: if np.isnan(feature_tensor).any(): # avoid NaN (zero division) feature_tensor = v return feature_tensor.flatten() # 3780 featuresdef main(img_path): img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) img = cv2.resize(src=img, dsize=(64, 128)) f = hog(img) print("Extracted feature vector of %s. Shape:" % img_path) print("Feature size:", f.shape) print("Features (HOG):", f) passif __name__ == "__main__": print("Start running HOG on image
" + "x1b<1;%dm" % (34) + " https://www.facebook.com/olympicmyviet.com.vn/" + "x1b<0m") print("* Join GVGroup for discussion
" + "x1b<1;%dm" % (34) + "https://www.facebook.com/groups/ip.gvgroup/" + "x1b<0m") print("* Thank you ^^~")
person.jpg (ảnh này đặt cạnh tệp tin hog.py, hoặc dùng hình ảnh khác của chúng ta có cùng tên file)