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

news2024/12/26 23:17:17

凸包特征检测

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

  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.shape
    y,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 = 0
        x2 = 1000 #设置得足够大 让直线得以显示
        y1 = (ro-a*x1)/b  # 计算两个点
        y2 = (ro-a*x2)/b
        
        cv2.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.shape
    fir1 = 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 = 255
    init_v = 127
    bar = cv2.createTrackbar(trackbar_name,'img_bar',init_v,max_v,thres)

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bilibiliDown-纯净B站视频解析提取工具

软件简介 bilibiliDown是一款简洁好用的B站视频下载工具&#xff0c;支持由UP主上传的单集&#xff0c;多集以及相关封面&#xff0c;弹幕&#xff0c;字幕&#xff0c;音乐&#xff0c;刮削等等&#xff0c;支持任意粒度批量组合&#xff0c;登录后支持到1080P&#xff0c;大…

Git Merge 实例教学:同步代码库与处理分支冲突的最佳实践

文章目录 前言一、git merge是什么&#xff1f;二、git merge基本用法1. 合并两个分支2. 合并时创建合并提交3. 快进合并&#xff08;Fast-forward Merge&#xff09;4. --abort参数5. --continue参数6. -X theirs参数 三、实际例子1. 更新仓库2. 将origin/main分支合并到当前分…

podman安装过程记录

最近注意到podman兼容docker镜像包&#xff0c;于是好奇心的驱动下&#xff0c;研究了一下 本来以为podman的desktop跟docker一样&#xff0c;最后发现podman桌面版是轻量级的&#xff0c;还需要安装podman的服务&#xff08;当然&#xff0c;是支持直接通过它的桌面版来安装其…

Linux系统中用户、用户组及文件权限的常用知识汇总

Linux为多用户多任务的操作系统&#xff0c;文件权限管理十分重要&#xff0c;每一个文件都有很多属性&#xff0c;合理的权限设置&#xff0c;可以确保数据不被未授权的人员访问&#xff0c;同时也能提高系统安全性。 本文将介绍Linux系统中用户、用户组及文件权限的常用知识…

【C++二分查找 前缀和 】1292. 元素和小于等于阈值的正方形的最大边长

本文涉及的基础知识点 C二分查找 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode1292. 元素和小于等于阈值的正方形的最大边长 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold。 请你返回元素总和小于或等于阈值的正…

C++ 设计模式——策略模式

策略模式 策略模式主要组成部分例一&#xff1a;逐步重构并引入策略模式第一步&#xff1a;初始实现第二步&#xff1a;提取共性并实现策略接口第三步&#xff1a;实现具体策略类第四步&#xff1a;实现上下文类策略模式 UML 图策略模式的 UML 图解析 例二&#xff1a;逐步重构…

主成分分析SPSS步骤+Matlab程序

SPSS 导入数据 主成分分析 参数设置 选择要压缩的变量 输出结果 越陡说明信息差越大&#xff0c;反之信息差越小 导出数据 双击可以复制 粘贴到matlab 计算 Matlab clc,clear data readmatrix(例2.xlsx); %将数据保存在txt文件中 data zscore(data); %数据的标准化 …

使用java加载、调用onnx模型(二)

目录 1、摘要 2、实现过程 2.1、依赖 2.2、imread 2.3、contiguous函数 2.3.1、转化示例 2.3.3、核心代码 2.4、Flatten拉直 2.5、最终结果 3、完整代码 1、摘要 在上一篇文章中 使用java加载、调用onnx模型_onnx java-CSDN博客 发现使用Java加载调用模型的分类结…

计算组合数:从n个不同元素中,选k个元素的方式数量math.comb()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 计算组合数&#xff1a; 从n个不同元素中&#xff0c; 选k个元素的方式数量 math.comb() 请问关于以下代码表述正确的选项是&#xff1f; import math print("【执行】math.comb(3, 2)…

线性代数证明:把行列式的某一行(列)的k倍加到另一行(列),行列式的值不变

线性代数证明 把行列式的某一行&#xff08;列&#xff09;的k倍加到另一行&#xff08;列&#xff09;&#xff0c;行列式的值不变&#xff1a; 注意五角星的位置要用到另一条性质&#xff1a;若行列式的某一行&#xff08;列&#xff09;的元素都是两数之和&#xff0c;则可以…

Ajax笔记总结(Xmind格式):第一天

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; ajax知识总结&#xff1a; 网络的参考模型&#xff1a; 1.物理层&#xff1a;源设备到目的设备 底层传输就是比特流 2.数据链路层 进行电信号的处理 进行数据的分组 3.网路层 进行数据包的传递 进行不同网络的…

菱形继承和虚继承

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

Avue实现动态查询与数据展示(附Demo)

目录 前言1. 基本知识2. Demo 前言 此框架为Avue-crud&#xff0c;推荐阅读&#xff1a; 【vue】avue-crud表单属性配置&#xff08;表格以及列&#xff09;Avue实现批量删除等功能&#xff08;附Demo&#xff09;Avue实现选择下拉框的多种方式Avue框架实现图表的基本知识 | …

凌晨突发!核心系统瘫痪,通过Signleton单例模式轻松搞定,但还是被裁员了...

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

selenium底层原理详解

目录 1、selenium版本的演变 1.1、Selenium 1.x&#xff08;Selenium RC时代&#xff09; 1.2、Selenium 2.x&#xff08;WebDriver整合时代&#xff09; 1.3、Selenium 3.x 2、selenium原理说明 3、源码说明 3.1、启动webdriver服务建立连接 3.2、发送操作 1、seleni…

flink车联网项目:维表离线同步(第69天)

系列文章目录 3.3 维表离线同步 3.3.1 思路 3.3.2 示例 3.3.3 其他表开发 3.3.4 部署 3.3.1.1 将表提交到生成环境 3.3.1.2 添加虚拟节点 3.3.1.3 配置计算节点 3.3.1.4 添加虚拟结束节点 3.3.1.5 提交到生产环境 3.3.1.6 发布 3.3.1.7 运维中心 3.3.1.8 补数据 3.3.1.9 补数据…

c++进阶------多态

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

机器学习/数据分析--通俗语言带你入门线性回归(结合案例)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 机器学习是深度学习和数据分析的基础&#xff0c;接下来将更新常见的机器学习算法注意&#xff1a;在打数学建模比赛中&#xff0c;机器学习用的也很多&a…

探索GitLab:从搭建到高效使用的实用指南

企业里为什么喜欢使用GitLab 一、GitLab简介二、搭建GitLab三、GitLab的权限管理3.1、用户注册3.2、创建用户组3.3、为用户组添加用户3.4、为工程添加访问权限 四、GitLab的code review五、团队知识管理六、总结 一、GitLab简介 GitLab是利用 Ruby on Rails 一个开源的版本管理…

Adobe Media Encoder ME 2023-23.6.6.2 解锁版下载安装教程 (专业的视频和音频编码渲染工具)

前言 Adobe Media Encoder&#xff08;简称Me&#xff09;是一款专业的音视频格式转码软件&#xff0c;文件格式转换软件。主要用来对音频和视频文件进行编码转换&#xff0c;支持格式非常多&#xff0c;使用系统预设设置&#xff0c;能更好的导出与相关设备兼容的文件。 一、…