.. _sec_bbox: Hộp phát hiện và giới hạn đối tượng =================================== Trong các phần trước (ví dụ: :numref:`sec_alexnet`—:numref:`sec_googlenet`), chúng tôi đã giới thiệu các mô hình khác nhau để phân loại hình ảnh. Trong các tác vụ phân loại hình ảnh, chúng tôi giả định rằng chỉ có \* một\* đối tượng chính trong hình ảnh và chúng tôi chỉ tập trung vào cách nhận dạng danh mục của nó. Tuy nhiên, thường có các đối tượng \* nhiều\* trong hình ảnh quan tâm. Chúng tôi không chỉ muốn biết danh mục của họ, mà còn là vị trí cụ thể của họ trong hình ảnh. Trong tầm nhìn máy tính, chúng tôi đề cập đến các tác vụ như *phát hiện đối tượng* (hoặc *nhận dạng đối tượng*). Phát hiện đối tượng đã được ứng dụng rộng rãi trong nhiều lĩnh vực. Ví dụ, tự lái cần lên kế hoạch cho các tuyến đường di chuyển bằng cách phát hiện vị trí của phương tiện, người đi bộ, đường xá và chướng ngại vật trong các hình ảnh video đã chụp. Bên cạnh đó, robot có thể sử dụng kỹ thuật này để phát hiện và bản địa hóa các đối tượng quan tâm trong suốt quá trình điều hướng môi trường. Hơn nữa, các hệ thống an ninh có thể cần phải phát hiện các vật bất thường, chẳng hạn như kẻ xâm nhập hoặc bom. Trong vài phần tiếp theo, chúng tôi sẽ giới thiệu một số phương pháp học sâu để phát hiện đối tượng. Chúng tôi sẽ bắt đầu với phần giới thiệu về *vị trí* (hoặc *locations*) của các đối tượng. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. code:: python %matplotlib inline from mxnet import image, np, npx from d2l import mxnet as d2l npx.set_np() .. raw:: html
.. raw:: html
.. code:: python %matplotlib inline import torch from d2l import torch as d2l .. raw:: html
.. raw:: html
.. code:: python %matplotlib inline import tensorflow as tf from d2l import tensorflow as d2l .. raw:: html
.. raw:: html
Chúng tôi sẽ tải hình ảnh mẫu được sử dụng trong phần này. Chúng ta có thể thấy rằng có một chú chó ở phía bên trái của hình ảnh và một con mèo bên phải. Chúng là hai đối tượng chính trong hình ảnh này. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. code:: python d2l.set_figsize() img = image.imread('../img/catdog.jpg').asnumpy() d2l.plt.imshow(img); .. figure:: output_bounding-box_d6b70e_15_0.svg .. raw:: html
.. raw:: html
.. code:: python d2l.set_figsize() img = d2l.plt.imread('../img/catdog.jpg') d2l.plt.imshow(img); .. figure:: output_bounding-box_d6b70e_18_0.svg .. raw:: html
.. raw:: html
.. code:: python d2l.set_figsize() img = d2l.plt.imread('../img/catdog.jpg') d2l.plt.imshow(img); .. figure:: output_bounding-box_d6b70e_21_0.svg .. raw:: html
.. raw:: html
Hộp giới hạn ------------ Trong phát hiện đối tượng, chúng ta thường sử dụng một hộp giới hạn \* để mô tả vị trí không gian của một đối tượng. Hộp giới hạn là hình chữ nhật, được xác định bởi tọa độ :math:`x` và :math:`y` của góc trên bên trái của hình chữ nhật và tọa độ như vậy của góc dưới bên phải. Một biểu diễn hộp giới hạn thường được sử dụng khác là tọa độ :math:`(x, y)`-trục của trung tâm hộp giới hạn, và chiều rộng và chiều cao của hộp. Ở đây chúng ta định nghĩa các hàm để chuyển đổi giữa hai các hàm này hai đại diện : ``box_corner_to_center`` chuyển đổi từ biểu diễn hai góc sang trình bày chiều rộng trung tâm và ``box_center_to_corner`` ngược lại. Đối số đầu vào ``boxes`` phải là một tensor hai chiều của hình dạng (:math:`n`, 4), trong đó :math:`n` là số hộp giới hạn. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. code:: python #@save def box_corner_to_center(boxes): """Convert from (upper-left, lower-right) to (center, width, height).""" x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] cx = (x1 + x2) / 2 cy = (y1 + y2) / 2 w = x2 - x1 h = y2 - y1 boxes = np.stack((cx, cy, w, h), axis=-1) return boxes #@save def box_center_to_corner(boxes): """Convert from (center, width, height) to (upper-left, lower-right).""" cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] x1 = cx - 0.5 * w y1 = cy - 0.5 * h x2 = cx + 0.5 * w y2 = cy + 0.5 * h boxes = np.stack((x1, y1, x2, y2), axis=-1) return boxes .. raw:: html
.. raw:: html
.. code:: python #@save def box_corner_to_center(boxes): """Convert from (upper-left, lower-right) to (center, width, height).""" x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] cx = (x1 + x2) / 2 cy = (y1 + y2) / 2 w = x2 - x1 h = y2 - y1 boxes = torch.stack((cx, cy, w, h), axis=-1) return boxes #@save def box_center_to_corner(boxes): """Convert from (center, width, height) to (upper-left, lower-right).""" cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] x1 = cx - 0.5 * w y1 = cy - 0.5 * h x2 = cx + 0.5 * w y2 = cy + 0.5 * h boxes = torch.stack((x1, y1, x2, y2), axis=-1) return boxes .. raw:: html
.. raw:: html
.. code:: python #@save def box_corner_to_center(boxes): """Convert from (upper-left, lower-right) to (center, width, height).""" x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] cx = (x1 + x2) / 2 cy = (y1 + y2) / 2 w = x2 - x1 h = y2 - y1 boxes = tf.stack((cx, cy, w, h), axis=-1) return boxes #@save def box_center_to_corner(boxes): """Convert from (center, width, height) to (upper-left, lower-right).""" cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3] x1 = cx - 0.5 * w y1 = cy - 0.5 * h x2 = cx + 0.5 * w y2 = cy + 0.5 * h boxes = tf.stack((x1, y1, x2, y2), axis=-1) return boxes .. raw:: html
.. raw:: html
Chúng tôi sẽ xác định các hộp giới hạn của chó và con mèo trong hình ảnh dựa trên thông tin tọa độ. Nguồn gốc của tọa độ trong hình ảnh là góc trên bên trái của hình ảnh, và bên phải và xuống là các hướng dương của các trục :math:`x` và :math:`y`, tương ứng. .. code:: python # Here `bbox` is the abbreviation for bounding box dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0] Chúng tôi có thể xác minh tính chính xác của hai chức năng chuyển đổi hộp giới hạn bằng cách chuyển đổi hai lần. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. code:: python boxes = np.array((dog_bbox, cat_bbox)) box_center_to_corner(box_corner_to_center(boxes)) == boxes .. parsed-literal:: :class: output array([[ True, True, True, True], [ True, True, True, True]]) .. raw:: html
.. raw:: html
.. code:: python boxes = torch.tensor((dog_bbox, cat_bbox)) box_center_to_corner(box_corner_to_center(boxes)) == boxes .. parsed-literal:: :class: output tensor([[True, True, True, True], [True, True, True, True]]) .. raw:: html
.. raw:: html
.. code:: python boxes = tf.constant((dog_bbox, cat_bbox)) box_center_to_corner(box_corner_to_center(boxes)) == boxes .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Hãy để chúng tôi vẽ các hộp giới hạn trong hình ảnh để kiểm tra xem chúng có chính xác không. Trước khi vẽ, chúng ta sẽ xác định một hàm helper ``bbox_to_rect``. Nó đại diện cho hộp giới hạn ở định dạng hộp giới hạn của gói ``matplotlib``. .. code:: python #@save def bbox_to_rect(bbox, color): """Convert bounding box to matplotlib format.""" # Convert the bounding box (upper-left x, upper-left y, lower-right x, # lower-right y) format to the matplotlib format: ((upper-left x, # upper-left y), width, height) return d2l.plt.Rectangle( xy=(bbox[0], bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1], fill=False, edgecolor=color, linewidth=2) Sau khi thêm các hộp giới hạn trên hình ảnh, chúng ta có thể thấy rằng đường viền chính của hai đối tượng về cơ bản nằm trong hai hộp. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. code:: python fig = d2l.plt.imshow(img) fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue')) fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red')); .. figure:: output_bounding-box_d6b70e_55_0.svg .. raw:: html
.. raw:: html
.. code:: python fig = d2l.plt.imshow(img) fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue')) fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red')); .. figure:: output_bounding-box_d6b70e_58_0.svg .. raw:: html
.. raw:: html
.. code:: python fig = d2l.plt.imshow(img) fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue')) fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red')); .. figure:: output_bounding-box_d6b70e_61_0.svg .. raw:: html
.. raw:: html
Tóm tắt ------- - Phát hiện đối tượng không chỉ nhận ra tất cả các đối tượng quan tâm trong hình ảnh, mà còn cả vị trí của chúng. Vị trí thường được biểu diễn bằng một hộp giới hạn hình chữ nhật. - Chúng ta có thể chuyển đổi giữa hai biểu diễn hộp giới hạn thường được sử dụng. Bài tập ------- 1. Tìm một hình ảnh khác và cố gắng gắn nhãn một hộp giới hạn chứa đối tượng. So sánh các hộp và danh mục giới hạn ghi nhãn: thường mất nhiều thời gian hơn? 2. Tại sao chiều trong cùng của đối số đầu vào ``boxes`` của ``box_corner_to_center`` và ``box_center_to_corner`` luôn là 4? .. raw:: html
mxnetpytorch
.. raw:: html
`Discussions `__ .. raw:: html
.. raw:: html
`Discussions `__ .. raw:: html
.. raw:: html