python opencv在图像上显示图形_如何使用OpenCV Python显示图像的轮廓?

首先,该示例仅向您展示如何使用简单近似绘制轮廓.请记住,即使您使用简单近似绘制轮廓,也会将其视为具有完全围绕矩形绘制的蓝色轮廓,如左图所示.只需将轮廓绘制到图像上,您将无法获得正确的图像.此外,您想比较两组轮廓 – 右侧的简化版本及左侧的完整表示.具体来说,您需要使用cv2.CHAIN_APPROX_NONE替换cv2.CHAIN_APPROX_SIMPLE标志以获取完整表示.有关更多详细信息,请查看findContours上的OpenCV文档:

http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours

此外,即使您将轮廓绘制到图像上,它也不会显示结果.你需要拨打cv2.imshow.但是,绘制轮廓本身并不会显示完整版和简化版之间的区别.教程提到你需要在每个轮廓点绘制圆圈,所以我们不应该使用cv2.drawContours来完成这项任务.你应该做的是提取轮廓点并在每个点绘制圆圈.

因此,创建两个图像,如下所示:

# Your code

import numpy as np

import cv2

im = cv2.imread('test.jpg')

imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(imgray,127,255,0)

## Step #1 - Detect contours using both methods on the same image

contours1, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

contours2, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

### Step #2 - Reshape to 2D matrices

contours1 = contours1[0].reshape(-1,2)

contours2 = contours2[0].reshape(-1,2)

### Step #3 - Draw the points as individual circles in the image

img1 = im.copy()

img2 = im.copy()

for (x, y) in contours1:

cv2.circle(img1, (x, y), 1, (255, 0, 0), 3)

for (x, y) in contours2:

cv2.circle(img2, (x, y), 1, (255, 0, 0), 3)

请注意,上面的代码适用于OpenCV 2.对于OpenCV 3,cv2.findContours还有一个输出,这是第一个在这种情况下可以忽略的输出:

_, contours1, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

_, contours2, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

现在让我们慢慢地浏览代码.代码的第一部分就是您提供的内容.现在我们进入新的领域.

步骤#1 – 使用两种方法检测轮廓

使用阈值图像,我们使用完整和简单近似检测轮廓.它存储在两个列表中,contours1和contours2.

步骤#2 – 重塑为2D矩阵

轮廓本身存储为NumPy数组列表.对于提供的简单图像,应该只检测到一个轮廓,因此提取出列表的第一个元素,然后使用numpy.reshape将3D矩阵重新整形为它们的2D形式,其中每一行是(x,y)点.

步骤#3 – 将点绘制为图像中的各个圆圈

下一步是从每组轮廓中取出每个(x,y)点并在图像上绘制它们.我们以彩色形式制作原始图像的两个副本,然后我们使用cv2.circle并迭代两组轮廓的每对(x,y)点并填充两个不同的图像 – 每组轮廓一个.

现在,要获得上面看到的数字,有两种方法可以做到这一点:

>创建一个将这两个结果并排存储的图像,然后显示该组合图像.

>使用matplotlib,结合子图和imshow,以便在一个窗口中显示两个图像.

我将告诉你如何使用这两种方法来做到这一点:

方法#1

只需将两个图像并排堆叠,然后显示图像:

out = np.hstack([img1, img2])

# Now show the image

cv2.imshow('Output', out)

cv2.waitKey(0)

cv2.destroyAllWindows()

我将它们水平堆叠,以便它们是组合图像,然后用cv2.imshow显示.

方法#2

import matplotlib.pyplot as plt

# Spawn a new figure

plt.figure()

# Show the first image on the left column

plt.subplot(1,2,1)

plt.imshow(img1[:,:,::-1])

# Turn off axis numbering

plt.axis('off')

# Show the second image on the right column

plt.subplot(1,2,2)

plt.imshow(img2[:,:,::-1])

# Turn off the axis numbering

plt.axis('off')

# Show the figure

plt.show()

这应该在整个图形窗口内的单独子图中显示两个图像.如果你看一下我在这里调用imshow的方式,你会发现我正在交换RGB通道,因为OpenCV以BGR格式读取图像.如果要使用matplotlib显示图像,则需要反转通道,因为图像是RGB格式(应该是这样).

要在注释中解决您的问题,您可以采用所需的轮廓结构(轮廓1或轮廓2)并搜索轮廓点.轮廓是所有可能轮廓的列表,并且在每个轮廓内是3D矩阵,其形状为N×1×2格式. N将是表示轮廓的点的总数.我将删除单个第二维,因此我们可以将其设为N x 2矩阵.另外,让我们现在使用轮廓的完整表示:

points = contours1[0].reshape(-1,2)

我将假设您的图像只有一个对象,因此我索引到指数为0的contours1.我解开矩阵使其成为单行向量,然后重新整形矩阵使其变为N x 2.接下来,我们可以通过以下方式找到最低点:

min_x = np.argmin(points[:,0])

min_point = points[min_x,:]

np.argmin在您提供的数组中查找最小值的位置.在这种情况下,我们希望沿x坐标或列操作.一旦找到这个位置,我们只需索引到我们的2D轮廓点阵列并提取出轮廓点.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值