【OpenCV_python】凸包检测 轮廓特征 直方图均衡化 模板匹配 霍夫变换

凸包特征检测

凸包就是图像的最小外接多边形,通过图像的轮廓点,找到距离最远的两个点的直线,根据直线找到距离最远的下一个点,直到所有的点被包围在多边形内

  1. 读取图像
  2. 二值化
  3. 找图像的轮廓
  4. 获取凸包点的坐标
  5. 绘制凸包点
  • convexHull 获得图像的凸包点
    • cv2.convexHull(points, hull=None, clockwise=False, returnPoints=True)
    • points 输入图像的轮廓
  • polylines 绘制图像的凸包点
    • cv2.polylines(image, pts, isClosed, color, thickness=1)
    • pts 二维数组,每个数组是一个多边形的每个坐标点
    • isClosed 是否闭合,True会连接起点和终点
    num = cv2.imread('./media/num310.png')num_gray = cv2.imread('./media/num310.png',cv2.IMREAD_GRAYSCALE) # 灰度_,num_erzhi = cv2.threshold(num_gray,127,255,cv2.THRESH_BINARY) # 二值化contours,h = cv2.findContours(num_erzhi,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  # 这里的轮廓有三套# cv2.drawContours(num,contours,-1,(0,255,0),2) # 绿色的轮廓hull = [cv2.convexHull(contours[i]) for i in range(3)]  # 每一套轮廓一个一套凸包点  生成凸包点的列表cv2.polylines(num,hull,True,(0,0,255),2  # 红色的凸包

在这里插入图片描述

在这里插入图片描述

轮廓特征查找

轮廓特征查找,就是绘制图像的外接矩形,最小外接矩形,最小外接圆

  1. 外接矩形
    通过遍历边缘点,所有边缘点的坐标最大值和最小值
    cv2.boundingRect() 返回左上角的坐标x,y和矩形的宽高w,h
num = cv2.imread('./media/num310.png')num_gray = cv2.imread('./media/num310.png',cv2.IMREAD_GRAYSCALE)_,num_erzhi = cv2.threshold(num_gray,127,255,cv2.THRESH_BINARY)contours,h = cv2.findContours(num_erzhi,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# cv2.drawContours(num,contours,-1,(0,255,0),2)# 外接矩形for cont in contours:x, y, w, h = cv2.boundingRect(cont) # 获得左上角的点和 矩形的宽和高cv2.rectangle(num,(x,y),(x+w,y+h),(127,127,0),2)cv2.imshow('num',num)

在这里插入图片描述

  1. 最小外接矩形
    使用旋转卡壳法
    以凸包的一条边为起始边,遍历凸包点,找到距离最远的凸包点,做起始边的平行线,找凸包点投影距离最远的点,作矩形剩下的两边,就得到了最小外接矩形
    minAreaRect 传入轮廓,计算出最小外接矩形,返回 坐标,宽度,高度,旋转角度
    boxPoints 把最小外接矩形得到的数组,转化为四个顶点坐标 4行二列 四个点
num = cv2.imread('./media/num310.png')num_gray = cv2.imread('./media/num310.png',cv2.IMREAD_GRAYSCALE)_,num_erzhi = cv2.threshold(num_gray,127,255,cv2.THRESH_BINARY)contours,h = cv2.findContours(num_erzhi,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# cv2.drawContours(num,contours,-1,(0,255,0),2)# 最小外接矩形 for cont in contours:rect = cv2.minAreaRect(cont)# 计算最小外接矩形 ((109.34503936767578, 167.05064392089844), (147.49758911132812, 67.03535461425781), 74.38900756835938)rect = cv2.boxPoints(rect).astype(np.int32) # 返回坐标,转化为整数cv2.drawContours(num,[rect],-1,(127,0,127),2)  # 连接点 也可以使用绘制先线遍历绘制cv2.imshow('num',num)

在这里插入图片描述

  1. 最小外接圆
    cv2.minEnclosingCircle 计算最小外接圆,返回圆心(x,y)和半径
    num = cv2.imread('./media/num310.png')num_gray = cv2.imread('./media/num310.png',cv2.IMREAD_GRAYSCALE)_,num_erzhi = cv2.threshold(num_gray,127,255,cv2.THRESH_BINARY)contours,h = cv2.findContours(num_erzhi,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# cv2.drawContours(num,contours,-1,(0,255,0),2)for cont in contours:(x,y),r = cv2.minEnclosingCircle(cont)cv2.circle(num,(int(x),int(y)),int(r),(200,200,0),2)  # 需要转化为整数

在这里插入图片描述

直方图均衡化

直方图,不同像素值的数量统计

  1. 绘制直方图
    nut = cv2.imread('./media/nut.png')hist = cv2.calcHist([nut],[0],mask=None,histSize=[256],ranges=[0,256])# 	每种像素值统计数量min_v,max_v,minloc,maxloc = cv2.minMaxLoc(hist)# 获得最大值  最小值  最小值的坐标   最大值的坐标bar = np.zeros((256,256,3),dtype=np.uint8)# 初始化图像  得到全黑的图像h = (max_v-min_v)*1.2 for i,value in enumerate(hist):higit = int((value/h)*256)  # 归一化 cv2.line(bar,(i,256),(i,256-higit),(127,0,127))  # 绘制直线cv2.imshow('bar',bar)

在这里插入图片描述

  1. 直方图均衡化
    通过把直方图拉平,让像素值分布个均匀,可以让提高图像的对比度。凸显图像的更多细节,较暗的区域更清晰,但是较亮的区域会更亮

通过统计每个像素点的比例,重新映射到0-255的范围

    nut = cv2.imread('./media/nut.png',cv2.IMREAD_GRAYSCALE)cv2.imshow('nut',nut)cv2.imshow('nut2',cv2.equalizeHist(nut))

在这里插入图片描述
在这里插入图片描述

  1. 对比度受限的直方图均衡化
    对小范围进行均衡化,然后合并图像,但是如果有斑点噪声点,会放大噪声点。
    直方图均衡化过程中引入一个对比度限制参数。如果有过大的极端值,会进行平滑处理
    通过对图像进行重采样,对小区域的图像分别进行直方图均衡化,进行插值,让小区域的图像合并更平滑
    clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None)
    clipLimit 对比度限制参数,设置一个大于1的值,会限制对比度增强的最大程度,避免过度放大噪声。
    tileGridSize 图像的分块大小

创建这个类之后使用apply处理图像

    clta = cv2.createCLAHE()nut3 = clta.apply(nut)cv2.imshow('nut3',nut3)

在这里插入图片描述

在这里插入图片描述

模板匹配

模板(小图)在一个较大的图中滑动比较,通过不同的比较方法判断是否匹配成功

res=cv2.matchTemplate(image, templ, method)
image 图像
templ模板
method 方法
返回匹配计算的结果,结果矩阵和原图相同,值的大小代表匹配的相似度

method:

  • cv2.TM_CCOEFF 相关系数匹配 计算模板和目标区域的两个均值,模板和目标的像素分别和其均值的差在相乘,再求和
  • cv2.TM_CCOEFF_NORMED 对相关系数匹配归一化 越接近1 匹配度越高
  • cv2.TM_CCORR 相关匹配 对应像素的乘积 越大匹配度越高
  • cv2.TM_CCORR_NORMED 相关匹配归一化 越大匹配度越高
  • cv2.TM_SQDIFF 平方差匹配 平方差公式 计算 对应像素的差的平方和
  • cv2.TM_SQDIFF_NORMED 归一化平方差 越小匹配度越高
    bg = cv2.imread('./media/game.png')templ = cv2.imread('./media/temp.png')bg_gray = cv2.cvtColor(bg,cv2.COLOR_RGB2GRAY)templ_gray = cv2.cvtColor(templ,cv2.COLOR_RGB2GRAY)result = cv2.matchTemplate(bg_gray,templ_gray,cv2.TM_SQDIFF_NORMED)h,w = templ_gray.shapey,x = np.where(result<0.2)  # 返回索引  for x,y in zip(x,y):cv2.rectangle(bg,(x,y),(x+w,y+h),(0,0,255),2)cv2.imshow('bg',bg)   cv2.imshow('templ',templ)   

在这里插入图片描述

霍夫变换

把图像中的像素点映射到霍夫空间,转换坐标系的表示。
每个像素点坐标,在霍夫空间中是一条直线,霍夫空间中的点在原图像的坐标空间是一条线。
在霍夫空间中,多条线交与一个点,在原图中就是多个点共线。
这里使用极坐标系进行表示

lines=cv2.HoughLines(image, rho, theta, threshold)

  • rho:r的精度,以像素为单位,表示霍夫空间中每一步的距离增量, 值越大,考虑越多的线。
  • theta:角度θ的精度,通常以弧度为单位,表示霍夫空间中每一步的角度增量。值越小,考虑越多的线。
  • threshold 阈值,直线上点的数量超过阈值才认为是一条直线
  • 返回二维数组,在霍夫空间的rho和theta
  1. 霍夫直线变换
    num = cv2.imread('./media/num310.png')num_gray = cv2.cvtColor(num,cv2.COLOR_BGR2GRAY)_,erzhi = cv2.threshold(num_gray,127,255,cv2.THRESH_BINARY)boder = cv2.Canny(erzhi,20,70)lines = cv2.HoughLines(boder,0.8,0.01,50)  # 边缘检测for line in lines:ro,theta = line[0] # 得到极坐标的两个值a = np.cos(theta)b = np.sin(theta)x1 = 0x2 = 1000 #设置得足够大 让直线得以显示y1 = (ro-a*x1)/b  # 计算两个点y2 = (ro-a*x2)/bcv2.line(num,(int(x1),int(y1)),(int(x2),int(y2)),(0,0,255),1) # 绘制直线cv2.imshow('num_gray',boder)cv2.imshow('num',num)

在这里插入图片描述

  1. 统计概率霍夫直线变换
    通过得到的直线的两个端点,统计连线上像素点的数量,通过设定的阈值筛选不符合条件的点
  • image:输入图像,白点表示边缘点=
  • rho:极径分辨率,表示极坐标系中的距离
  • theta:极角分辨率,以弧度为单位
  • threshold:阈值,过滤掉弱检测结果
  • lines(可选):一个可初始化的输出数组,用于存储检测到的直线参数。
  • minLineLength(可选):最短长度阈值
  • maxLineGap(可选):同一直线两点之间的最大距离
    • 如果maxLineGap设置得较小,那么只有相邻且间距很小的线段才会被连接起来,这可能导致检测到的直线数量较多,但更准确地反映了图像中的局部直线结构。
    • 如果maxLineGap设置得较大,则线段间的间距可以更大,这样可能会合并更多的局部线段成为更长的直线,但有可能会将原本不属于同一直线的线段误连接起来。
    lines = cv2.HoughLinesP(boder,0.8,0.01,50,minLineLength=60,maxLineGap=400)# print(lines.shape) # (2, 1, 4)for line in lines:x1,y1,x2,y2 = line[0]cv2.line(num,(x1,y1),(x2,y2),(0,0,255),1)cv2.imshow('num_gray',boder)cv2.imshow('num',num)

在这里插入图片描述

  1. 霍夫圆变换
    circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)
  • image:输入图像,灰度图像

  • method:使用的霍夫变换方法 cv2.HOUGH_GRADIENT

  • dp:设置为1表示霍夫梯度法中累加器图像的分辨率与原图一致

  • minDist:检测到的圆心之间的最小允许距离,以像素为单位。

  • param1param2:这两个参数是在使用 cv2.HOUGH_GRADIENT 方法时的特定参数

    • param1(可选):阈值1,决定边缘强度的阈值。

    • param2:阈值2,控制圆心识别的精确度。

    cirs = cv2.HoughCircles(num_gray,cv2.HOUGH_GRADIENT,1,400,param2=50)for c in cirs[0,:]:# print(c)cv2.circle(num,(int(c[0]),int(c[1])),int(c[2]),(0,255,0))cv2.imshow('num_gray',num_gray)cv2.imshow('num',num)

亮度变换 窗口管理 滑动条

通过对图像中的数据进行操作达到亮度透明度的变换
所有像素加一个值,亮度增大,减一个值,亮度减小

线性变换
cv2.addWeighted(src1, alpha, src2, beta, gamma)
alpha 第一个图的权重
beta 第二个图的权重
gamma 偏置,亮度补偿 整体加上这个值

直接像素值修改
numpy.clip(a, a_min, a_max)
小于a_min 修改为a_min
大于a_max修改为a_max

    nut = cv2.imread('./media/nut.png')h,w,_ = nut.shapefir1 = cv2.imread('./media/1.jpg')fir2 = fir1[100:h+100,100:w+100]img = cv2.addWeighted(fir2,1,nut,0.5,10)cv2.imshow('nut',nut)cv2.imshow('fir1',fir1)cv2.imshow('img',img)

在这里插入图片描述

窗口管理 滑动条
创建窗口cv2.namedWindow(str)
创建滑块
bar = cv2.createTrackbar(trackbar_name,‘img_bar’,init_v,max_v,thres)
trackbar_name 滑块名称
要显示的窗口名
初始值
最大值,最小值是0
函数 拖动滑块,把滑块的值传入这个函数,并调用这个函数


cv2.namedWindow('img_bar')def thres(x):fir1 = cv2.imread('./media/1.jpg')fir1 = cv2.cvtColor(fir1,cv2.COLOR_BGR2GRAY)_,erzhi = cv2.threshold(fir1,x,255,cv2.THRESH_BINARY)cv2.imshow('img_bar',erzhi)trackbar_name = 'threshold'max_v = 255init_v = 127bar = cv2.createTrackbar(trackbar_name,'img_bar',init_v,max_v,thres)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403719.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员如何写PLC程序

PLC是可编程逻辑控制器的简称&#xff0c;常用的编程语言是IEC61131-3&#xff08;梯形图、结构化文本、指令表、功能块、顺序功能图&#xff09;和西门子的SCL。程序员常用的编程语言是JS、Java、Python、C/C、Go等。PLC广泛采用编程工具有codesys、博图等。程序员常用的编程工…

敏捷架构在数字时代的应用:从理论到实践的全面指南

在数字化转型和技术变革的浪潮中&#xff0c;企业面临着不断提升敏捷性和应对复杂环境的挑战。敏捷架构在数字时代的应用不仅从理论层面阐述了敏捷架构的基本原理&#xff0c;还为企业提供了详细的实践指南&#xff0c;帮助企业从理论走向实际操作。本文将从理论与实践的双重视…

STM32——CAN通讯基础知识

CAN 协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称&#xff0c;它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的&#xff0c;并最终成为国际标准(ISO11519以及ISO11898),是国际上应用最广泛的现场总线之一。差异点如下&#xff1a; 高速CAN可以达…

YOLOv8_det/seg/pose/obb推理流程

本章将介绍目标检测、实例分割、关键点检测和旋转目标检测的推理原理,基于onnx模型推理,那么首先就需要了解onnx模型的输入和输出,对输入的图片需要进行预处理的操作,对输出的结果需要进行后处理的操作,这部分内容在我的另一个专栏《YOLOv8深度剖析》中也有介绍,如果对YO…

《机器学习》一元、多元线性回归的实现 No.4

一、一元线性回归实现 先直接看完整代码&#xff1a; import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegressiondate pd.read_csv(data.csv) #导入数据plt.scatter(date[广告投入],date[销售额]) # 用散点图展示数据 plt.sh…

实训第二十八天(haproxy与利用python实现mysql主从的读写分离)

1、练习 [rootnat ~]# ipvsadm -d -t 192.168.10.101:3306 -r 10.0.0.22:3306 #删除真实主机 nat: [rootnat ~]# ifconfig ens33: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.0.10 netmask 255.255.255.0 broadcast 10.0.0.25…

【JVM】深入理解类加载机制(二)

深入理解类加载机制 HSDB工具的使用 Hotspot Debugger(HSDB):JDK原生自带 以Windows系统为例&#xff0c;jdk8的环境&#xff0c;在jdk的lib目录下&#xff0c;启动之前&#xff0c;你需要确保你进入的lib目录和你当前的JAVA_HOME配置的JDK是相同的&#xff0c;否则可能会出现…

2.1 文件内容差异对比方法

2.1 文件内容差异对比方法 文件内容差异对比方法2.1.1 两个字符串的差异对比2.1.2 生成美观的HTML格式文档2.1.3 对比nginx 配置文件差异代码封装 文件内容差异对比方法 介绍如何通过difflib模块实现文件内容差异对比。difflib作为Python的标准库模块无需安装&#xff0c;作用…

2024年运营技术与网络安全态势研究报告:遭遇多次网络威胁的比例暴增

随着 OT 组织不断在其业务环境中集成各种数字工具和技术&#xff0c;它们面临的安全挑战也日益变得愈加复杂和多样化。正如 NIST 指出&#xff0c; “虽然安全解决方案旨在解决典型 IT系统中的一些问题&#xff0c;但将这些相同的解决方案引入不同的 OT 环境时&#xff0c;必须…

ruoyi-vue-pro项目新建模块的接口都报404错误

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 新建模块之后,该模块后端的请求都是返回404,如图所示: 2. 原理分析 抛开这个项目,对于路径请求不成功,返回404 主要的步骤如下: 检查路由配置: 确保在路由配置文件中添加了新模块的路由 例如,在Spring Boot中,这…

vue3+ts 前端word文档下载文件时不预览直接下载方法(支持 doc / excel / ppt / pdf 等)

前端word文档下载文件时不预览直接下载方法支持 doc / excel / ppt / pdf 等 根据需要&#xff0c;要实现一个下载文档的需要 最简单的方法就是使用a标签 如果是相同域可以直接下载&#xff0c;但如果是不同域的&#xff0c;就会先打开一个预览页&#xff0c;在预览页再点下载…

StarRocks Lakehouse 快速入门——Apache Paimon

StarRocks Lakehouse 快速入门指南为您提供了湖仓技术概览&#xff0c;旨在帮助您迅速掌握其核心特性、独特优势和应用场景。本指南将指导您如何高效地利用 StarRocks 构建解决方案。文章末尾&#xff0c;我们集合了来自阿里云、饿了么、喜马拉雅和同程旅行等行业领导者在 Star…

Eureka原理与实践:构建高效的微服务架构

Eureka原理与实践&#xff1a;构建高效的微服务架构 Eureka的核心原理Eureka Server&#xff1a;服务注册中心Eureka Client&#xff1a;服务提供者与服务消费者 Eureka的实践应用集成Eureka到Spring Cloud项目中创建Eureka Server创建Eureka Client&#xff08;服务提供者&…

什么叫日志门面

日志门面&#xff0c;是门面模式的一个典型的应用。 门面模式&#xff08;Facade Pattern&#xff09;&#xff0c;也称之为外观模式&#xff0c;其核心为&#xff1a;外部与一个子系统的通信必须通过一个统一的外观对象进行&#xff0c;使得子系统更易于使用。 就像Log4j、Lo…

stm32智能颜色送餐小车(ESP8266WIFI模块、APP制作、物联网模型建立、MQTTFX)

大家好啊&#xff0c;我是情谊&#xff0c;今天我们来介绍一下我最近设计的stm32产品&#xff0c;我们在今年七月份的时候参加了光电设计大赛&#xff0c;我们小队使用的就是stm32的智能送餐小车&#xff0c;虽然止步于省赛&#xff0c;但是还是一次成长的经验吧&#xff0c;那…

Linux系统-通用权限管理

目录 一、文件类型 二、通用权限 1.文件的常规权限 权限类型 壹.对于文件&#xff1a; 贰.对于目录&#xff1a; 查看和修改权限 说明&#xff1a; 举例&#xff1a; 字母表示法 数字表示法 2.文件的访问控制列表&#xff08;FACL File access control list&#…

菱形继承和虚继承

菱形继承&#xff08;Diamond Inheritance&#xff09;是指在多重继承的情况下&#xff0c;某个类继承自两个类&#xff0c;而这两个类又都继承自同一个基类的情况。 在这个结构中&#xff0c;D 直接从 A 继承了 A 的所有特性&#xff0c;但通过 B 和 C 继承&#xff0c;这会导…

eNSP 华为三层交换机配置DHCP

华为三层交换机配置DHCP 华为DHCP原理&#xff1a;&#xff08;思科四个都是广播包&#xff09; 1、客户端广播发送DHCP Discover包。用于发现当前局域网中的DHCP服务器。 2、DHCP服务器单播发送DHCP Offer包给客户端。携带分配给客户端的IP地址。 3、客户端广播发送DHCP Resqe…

索引的数据结构

1.举例引出索引: 1.1.什么是索引&#xff1a; 1.2.数据查找分析&#xff1a; a.数据查找&#xff1a; 1.如上图所示&#xff0c;数据库没有索引的情况下&#xff0c;数据分布在硬盘不同的位置上面&#xff0c;读取数据时&#xff0c;摆臂需要前后摆动查找数据&#xff0c;这…

Java方法04:命令行传递参数

本节视频链接&#xff1a;https://www.bilibili.com/video/BV12J41137hu?p48&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5https://www.bilibili.com/video/BV12J41137hu?p48&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 在Java中&#xff0c;‌命令行传递参数…