首页 > 编程语言 >使用 OpenCV 进行轮廓检测 (Python/C++)第一部分

使用 OpenCV 进行轮廓检测 (Python/C++)第一部分

时间:2023-05-26 20:00:36浏览次数:34  
标签:阈值 Python image cv2 C++ OpenCV 灰度 图像 轮廓

什么是轮廓

当我们连接一个对象边界上的所有点时,我们得到一个轮廓。通常,特定轮廓是指具有相同颜色和强度的边界像素。OpenCV 使得在图像中查找和绘制轮廓变得非常容易。它提供了两个简单的功能:

  1. findContours()
  2. drawContours()

此外,它有两种不同的轮廓检测算法:

  1. CHAIN_APPROX_SIMPLE
  2. CHAIN_APPROX_NONE

我们将在下面的示例中详细介绍这些内容。下图显示了这些算法如何检测简单物体的

在 OpenCV 中检测和绘制轮廓的步骤

OpenCV 使这成为一项相当简单的任务。只需按照以下步骤操作:

  1. 读取图像并将其转换为灰度格式

读取图像并将图像转换为灰度格式。将图像转换为灰度非常重要,因为它为下一步准备图像。将图像转换为单通道灰度图像对于阈值处理很重要,这反过来又是轮廓检测算法正常工作所必需的。

  1. 应用二进制阈值

在查找轮廓时,首先始终对灰度图像应用二进制阈值处理或 Canny 边缘检测。在这里,我们将应用二进制阈值。

这会将图像转换为黑白图像,突出显示感兴趣的对象,以便于轮廓检测算法。阈值处理将图像中对象的边界完全变白,所有像素都具有相同的强度。该算法现在可以从这些白色像素中检测到对象的边界。

注意:值为 0 的黑色像素被视为背景像素并被忽略。

此时,可能会出现一个问题。如果我们使用 R(红色)、G(绿色)或 B(蓝色)等单通道而不是灰度(阈值)图像会怎样?在这种情况下,轮廓检测算法将无法正常工作。正如我们之前所讨论的,该算法会寻找边界和相似强度的像素来检测轮廓。二值图像提供的信息比单个 (RGB) 颜色通道图像好得多。在博客的后面部分,我们将在仅使用单个 R、G 或 B 通道而不是灰度和阈值图像时得到结果图像。

  1. 找到轮廓

使用该findContours()函数检测图像中的轮廓。

  1. 在原始 RGB 图像上绘制轮廓。

识别出轮廓后,使用该drawContours()函数将轮廓叠加在原始 RGB 图像上。

当我们开始编码时,上面的步骤会更有意义,并且会变得更加清晰。

使用 OpenCV 查找和绘制轮廓

首先导入 OpenCV,然后读取输入图像。

Python:

import cv2
 
# read the image
image = cv2.imread('input/image_1.jpg')

C++:

#include<opencv2/opencv.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
int main() {
   // read the image
   Mat image = imread("input/image_1.jpg");

接下来,使用cvtColor()函数将原始 RGB 图像转换为灰度图像。 

Python:

# convert the image to grayscale format
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

C++:

// convert the image to grayscale format
Mat img_gray;
cvtColor(image, img_gray, COLOR_BGR2GRAY);

现在,使用该threshold()函数对图像应用二进制阈值。任何值大于 150 的像素都将设置为值 255(白色)。结果图像中的所有剩余像素都将设置为 0(黑色)。阈值 150 是一个可调参数,因此您可以对其进行试验。 

imshow()阈值处理后,使用如下所示的函数 可视化二值图像。

Python:

# apply binary thresholding
ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)
# visualize the binary image
cv2.imshow('Binary image', thresh)
cv2.waitKey(0)
cv2.imwrite('image_thres1.jpg', thresh)
cv2.destroyAllWindows()

C++:

// apply binary thresholding
Mat thresh;
threshold(img_gray, thresh, 150, 255, THRESH_BINARY);
imshow("Binary mage", thresh);
waitKey(0);
imwrite("image_thres1.jpg", thresh);
destroyAllWindows();

使用 OpenCV 进行轮廓检测 (Python/C++)第一部分_轮廓检测

标签:阈值,Python,image,cv2,C++,OpenCV,灰度,图像,轮廓
From: https://blog.51cto.com/u_15959862/6358439

相关文章

  • C++类的基础、构造、析构
    双向链表节点——具体的表表里面要维护什么是由你自己来决定的以链表为例讲解为什么需要类用户修改了你的链表,暴露给所有人创建和销毁,忘记了,内存泄漏冗长的名字封装分离实现细节和接口一定要把细节private接口public接口修改调用我们是知道的......
  • c++打卡练习(40)(大一最后一次)
    求可逆素数若一个四位数的素数把它倒序过来还是素数,那么称它为可逆素数,如1009和9001就是一对可逆素数流程图:伪代码:源代码:#include<iostream>usingnamespacestd;intmain(){ intstart,end,i,j,m=0; for(i=1000;i<=9999;i++){ intk=0; for(j=2;j<i;j++){ if(i%j==0){ ......
  • Python Web开发:深入剖析Web框架及其实现方式
    1.引言在现代Web应用程序开发中,Python是最受欢迎的编程语言之一。它是一种高级、通用、解释性的语言,被广泛应用于开发Web应用程序、科学计算、数据分析、视觉化和人工智能等领域。Python语言旨在提高开发者的生产力,并让他们以更少的代码实现更多的功能。在本文中,我们将讨论Python......
  • Numpy_矩阵的multiply_python的属性以及类特性_装饰器——@property_@classmethod_@st
    Python类中有三个常用的装饰器分别是@property(使一个方法可以被当成属性调用,常用于直接返回某一不想被修改的属性)@classmethod(将一个方法定义为类方法,其中第一个参数要修改为cls,使得该方法可以不用实例化即可被调用)@staticmethod(静态方法,类似于类方法,也可以不用实例化,......
  • python操作mysql数据pymysql-执行语句select查询返回值直接返回dict字典类型或者list
    一、返回tuple元组类型(默认)fetchall()将结果放在二维数组里面,每一行的结果在元组里面importpymysqldefexport(table_name):conn=pymysql.connect(host='118.24.3.40',user='jxz',password='123456',db......
  • python基础day12 函数的参数
    函数参数的两大分类1.形式参数在函数定义阶段括号内一次写入的变量名就叫形式参数,简称“形参”defindex(a,b,c,d)pass#a,b,c,d就称之为是函数的形参2.实际参数在函数调用阶段括号内一次传入的变量值就叫实际参数,简称“实参”index(1,2,3,4)#1,2,3,4就称之为......
  • python中re正则一些用法及其常用正则表达式
    re.findall(pattern,string[,flags])re.findall(pattern,string[,flags])是Pythonre模块中的函数,用于在字符串中查找所有与正则表达式模式匹配的非重叠子字符串,并将它们作为列表返回。具体参数解释如下:pattern:一个正则表达式模式,用于指定要匹配的模式。string:要在其......
  • python flask 启动报错 'utf-8' codec can't decode byte 0xb2 in position 4: invali
    原因:在python下lib文件夹里的socket.py文件中的name=gethostname()代码执行获取本机电脑名称时,遇到中文导致乱码报错。解决方法:    1.将电脑“设备名称”中中文改为英文;    2.修改socket.py代码,如下(参考https://blog.csdn.net/weixin_46342884/article/detail......
  • python基础12
    函数参数的两大分类1.形式参数在函数定义阶段括号内依次写入的变量名就叫形式参数,简称‘形参’2.实际参数在函数调用阶段括号里一次传入的变量值就叫实际参数,简称‘实参’3.形式参数和实际参数之间的关系把实际参数传递给形式参数,以形参=实参的形式传入——一变......
  • C++文件流结构体序列化,并查集,LRU缓存
    c语言中的文件操作中用fprintf将数据写入到文件中,用fscanf将文件读入内存中,而c++中也有ostream和istream作为键盘流输入,屏幕流输出,对于文件也有ofstream/istream来进行相关的操作.如图:图中表示将一个结构体的的数据输入到文件中,并从文件中读取数据,并用得到的数据初始化一......