# 框住水鸭子 OpenCV 里的连通区域分析可以将具有相同像素值且位置相邻的前景像素点组成的图像区域识别出来。有两种像素相邻的定义: ![](./pixel_region.jpg) 通过OpenCV的连通区域分析算法,我们可以将下图的水鸭子的外框框出来: ![](./duck_box.png) 框架代码如下: ```python import cv2 import numpy as np import matplotlib.pyplot as plt def close_op(img): kernel = np.ones((3, 3), np.uint8) img1 = cv2.dilate(img, kernel, iterations=1) img2 = cv2.erode(img1, kernel, iterations=1) return img2 def show_images(images): i = 0 for title in images: plt.subplot(2, 3, i+1), plt.imshow(images[title], 'gray') plt.title(title) plt.xticks([]), plt.yticks([]) i += 1 plt.show() if __name__ == '__main__': duck_origin = cv2.imread('duck.jpeg', -1) duck_box = duck_origin.copy() duck_gray = cv2.cvtColor(duck_box, cv2.COLOR_BGR2GRAY) duck_gray_with_closed = close_op(duck_gray) ret, duck_binary = cv2.threshold(duck_gray_with_closed, 127, 255, cv2.THRESH_BINARY) # TODO(You): 请实现识别鸭子区域并用框出来的代码 images = { 'duck_origin': duck_origin, 'duck_gray': duck_gray, 'duck_gray_with_closed_op': duck_gray_with_closed, 'duck_binary': duck_binary, 'duck_box': duck_box } show_images(images) ``` 以下代码实现正确的是? ## 答案 ```python ret, labels, stats, centroid = cv2.connectedComponentsWithStats(duck_binary) duck_area = sorted(stats, key=lambda s: s[-1], reverse=False)[-2] cv2.rectangle( duck_box, (duck_area[0], duck_area[1]), (duck_area[0] + duck_area[2], duck_area[1] + duck_area[3]), (255, 0, 0), 3 ) ``` ## 选项 ### 排序后取错位置 ```python ret, labels, stats, centroid = cv2.connectedComponentsWithStats(duck_binary) duck_area = sorted(stats, key=lambda s: s[-1], reverse=False)[-1] cv2.rectangle( duck_box, (duck_area[0], duck_area[1]), (duck_area[0] + duck_area[2], duck_area[1] + duck_area[3]), (255, 0, 0), 3 ) ``` ### 连通分析传入了灰度图 ```python ret, labels, stats, centroid = cv2.connectedComponentsWithStats(duck_gray) duck_area = sorted(stats, key=lambda s: s[-1], reverse=False)[-1] cv2.rectangle( duck_box, (duck_area[0], duck_area[1]), (duck_area[0] + duck_area[2], duck_area[1] + duck_area[3]), (255, 0, 0), 3 ) ``` ### 矩形框画错 ```python ret, labels, stats, centroid = cv2.connectedComponentsWithStats(duck_binary) duck_area = sorted(stats, key=lambda s: s[-1], reverse=False)[-1] cv2.rectangle( duck_box, (duck_area[0], duck_area[1]), (duck_area[2], duck_area[3]), (255, 0, 0), 3 ) ```