【python-opencv】硬币检测

2023-11-20

使用 python3.8.x,opencv

问题描述

  1. 使用图像处理技术,从照片中识别硬币的个数,并判断总价值。
    硬币图片

设计思路1

使用简单特征识别

  1. 使用颜色特征,识别出5角硬币
  2. 使用半径大小,判断出1角和1元硬币。

具体操作

  1. 将图片转换为HSV颜色模型
    HSV基本颜色分量
hsv = cv2.cvtColor(imgROI, cv2.COLOR_BGR2HSV)
lowerYellowHSV = np.array([11,43,46])
upperYellowHSV = np.array([34,255,255])
mask=cv2.inRange(hsv,lowerb=lowerYellowHSV,upperb=upperYellowHSV)/255

对比

部分代码

def coinSimpleDetection(img,circlesVector):
    # 简单识别,利用硬币的色彩和半径进行区分

    circlesNum = circlesVector.shape[0]
    # 将图片裁剪出来
    candidateImage = {}
    for i in range(circlesNum):
        information = {"radius":0,"value":0}
        col,row,radius = circlesVector[i,:]
        imgTemp = img.copy()
        imgROI = imgTemp[row-radius:row+radius,col-radius:col+radius,:]
        information["radius"] = radius

        # 识别5角硬币
        hsv = cv2.cvtColor(imgROI, cv2.COLOR_BGR2HSV)
        lowerYellowHSV = np.array([11,43,46])
        upperYellowHSV = np.array([34,255,255])
        mask=cv2.inRange(hsv,lowerb=lowerYellowHSV,upperb=upperYellowHSV)/255
        if np.sum(np.array(mask))/((row+2*radius)*(col+2*radius)) > 0.05:
            information["value"] = 0.5

        # 根据半径判断1块,新旧1角硬币
        if information["value"] == 0:
            if information["radius"] > 180 and information["radius"] < 250:
                information["value"] = 0.1
            if information["radius"] > 250 and information["radius"] < 300:
                information["value"] = 1.0
        candidateImage.update({i:information})
    cionsValue = np.sum([candidateImage[k]["value"] for k in range(circlesNum)])
    return candidateImage,cionsValue

设计思路2

模板匹配

  1. 提取轮廓信息 cv2.findContours()
  2. 拟合椭圆,提取ROI cv2.fitEllipse()
  3. 模板匹配cv2.matchTemplate()
  4. 选取最优匹配
    模板匹配

源码

模板制作

有同学说不知道如何制作模板,其实,只需要将上面所说的模板匹配过程执行一半,获取到ROI之后,分别保存下来即可。
我把模板制作代码完整地贴出来吧

"""
模板制作
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 参数给定
numOfTimeToBlur = 3 # 去噪次数
blurKernelSize = 5 # 去噪核大小
cannyThreshold = 100 # canny 算子的低阈值
cannyThreshold2 = 2*cannyThreshold # canny 算子的高阈值,一般为低阈值的2~3倍
minAreaOfCircle = 800 # 最小圆形面积
numberOfTemplates = 8
threshold1=[50,50,50,50,20,30,40,30]
threshold2=[120,120,120,120,40,60,80,60]

# 图片路径
sourceImgPath = ".\\coin Image\\Test Image\\coin.jpg"
templateImgPath = ".\\coin Image\\Template Images\\"

if __name__ == "__main__":
    # 0.1 图像读取
    sourceImg = cv2.imread(sourceImgPath,cv2.IMREAD_COLOR)
    contourFilledWithColorImg = sourceImg.copy()

    # 1.1 转换为灰度图
    sourceImgGray = cv2.cvtColor(sourceImg,cv2.COLOR_BGR2GRAY)

    # 1.2 图像去噪
    for i in range(0,numOfTimeToBlur):
        sourceImgGray = cv2.GaussianBlur(sourceImgGray,(blurKernelSize,blurKernelSize),2.0,2.0)

    # 1.3 Canny 边缘检测
    sourceImgCanny = cv2.Canny(sourceImgGray,cannyThreshold,cannyThreshold2)

    # 1.4 膨胀canny图像
    dilationKernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3),(1,1))
    cv2.dilate(sourceImgCanny,dilationKernel,sourceImgCanny)

    # 1.5 在边缘中找轮廓
    # CV_RETR_EXTERNAL只检测最外围轮廓
    # CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息
    contours, _ = cv2.findContours(sourceImgCanny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

    # 2 遍历每一个找到的轮廓
    matchingContours = []
    for currentContour in range(0,len(contours)):
        # 2.1 轮廓拐点小于5或者小于最小面积限制,跳过
        if len(contours[currentContour]) < 5 or cv2.contourArea(contours[currentContour])<= minAreaOfCircle:
            continue

        # 2.2 创建形状包围轮廓,得到轮廓的边界矩形的顶点和其相反点
        # boundingRectVals = cv2.boundingRect(contours[currentContour]) # x y w h
        boundingRect_x,boundingRect_y,boundingRect_w,boundingRect_h = cv2.boundingRect(contours[currentContour])
        p1 = (boundingRect_x,boundingRect_y)
        p2 = (boundingRect_x+boundingRect_w,boundingRect_y+boundingRect_h)
        bottom = (boundingRect_x,boundingRect_y + boundingRect_h + 50)

        # 2.3 求轮廓的外接椭圆
        ellipse = cv2.fitEllipse(contours[currentContour]) # [ (x, y) , (a, b), angle ] 椭圆中心位置,长短轴,旋转角度

        # 2.4 用红色绘制外接椭圆
        # 【这里进行绘制,会导致patch中有红色线,故将其移动到保存patch之后】
        # cv2.ellipse(sourceImg,ellipse,(0,0,255),3,cv2.LINE_AA)

        # 3 模板匹配
        # 3.1 创建与轮廓周围的边界矩形大小相同的patch
        patch = np.zeros((boundingRect_h,boundingRect_w,3),np.uint8)

        # 3.2 为轮廓区域填充颜色
        cv2.ellipse(contourFilledWithColorImg,ellipse,(111,222,111),cv2.FILLED,cv2.LINE_AA)

        # 3.3 创建填充的patch,用于从图像中提取硬币而忽略背景
        patchFilled = patch.copy()

        # 3.4 提取轮廓范围内的像素到patch
        sourceRow = boundingRect_y

        for patchRow in range(patch.shape[0]):
            sourceCol = boundingRect_x
            for patchCol in range(patch.shape[1]):
                patchFilled[patchRow,patchCol,:] = contourFilledWithColorImg[sourceRow,sourceCol,:]
                if patchFilled[patchRow,patchCol,0] == 111 and patchFilled[patchRow,patchCol,1] == 222 and patchFilled[patchRow,patchCol,2] == 111:
                    patch[patchRow,patchCol,:] = sourceImg[sourceRow,sourceCol,:]
                sourceCol += 1
            sourceRow += 1

        # 3.5 保存每一个patch为模板
        fpath = templateImgPath + "{}.jpg".format(currentContour)
        print(fpath)
        cv2.imwrite(fpath,patch)

        # 用红色绘制外接椭圆
        cv2.ellipse(sourceImg,ellipse,(0,0,255),3,cv2.LINE_AA)

    cv2.namedWindow("sourceImg",cv2.WINDOW_NORMAL|cv2.WINDOW_KEEPRATIO)
    cv2.imshow("sourceImg",sourceImg)
    cv2.waitKey(0)

完整代码

链接
https://download.csdn.net/download/weixin_44545174/87391095

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【python-opencv】硬币检测 的相关文章

  • 使用 python requests 模块时出现 HTTP 503 错误

    我正在尝试发出 HTTP 请求 但当前可以从 Firefox 浏览器访问的网站响应 503 错误 代码本身非常简单 在网上搜索一番后我添加了user Agent请求参数 但也没有帮助 有人能解释一下如何消除这个 503 错误吗 顺便说一句
  • Django 的内联管理:一个“预填充”字段

    我正在开发我的第一个 Django 项目 我希望用户能够在管理中创建自定义表单 并向其中添加字段当他或她需要它们时 为此 我在我的项目中添加了一个可重用的应用程序 可在 github 上找到 https github com stephen
  • 将 4 通道图像转换为 3 通道图像

    我正在使用 OpenCV 2 4 6 我正在尝试将 4 通道 RGB IplImage 转换为 4 通道 HSV 图像 下面是我的代码 给出错误 OpenCV 错误 未知函数断言失败 我认为 cvCvtColor 支持 3 通道图像 有没有
  • 将html数据解析成python列表进行操作

    我正在尝试读取 html 网站并提取其数据 例如 我想查看公司过去 5 年的 EPS 每股收益 基本上 我可以读入它 并且可以使用 BeautifulSoup 或 html2text 创建一个巨大的文本块 然后我想搜索该文件 我一直在使用
  • 独立滚动矩阵的行

    我有一个矩阵 准确地说 是 2d numpy ndarray A np array 4 0 0 1 2 3 0 0 5 我想滚动每一行A根据另一个数组中的滚动值独立地 r np array 2 0 1 也就是说 我想这样做 print np
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • 使用 xlrd 打开 BytesIO (xlsx)

    我正在使用 Django 需要读取上传的 xlsx 文件的工作表和单元格 使用 xlrd 应该可以 但因为文件必须保留在内存中并且可能不会保存到我不知道如何继续的位置 本例中的起点是一个带有上传输入和提交按钮的网页 提交后 文件被捕获req
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • Python,将函数的输出重定向到文件中

    我正在尝试将函数的输出存储到Python中的文件中 我想做的是这样的 def test print This is a Test file open Log a file write test file close 但是当我这样做时 我收到
  • 如何在不丢失注释和格式的情况下更新 YAML 文件 / Python 中的 YAML 自动重构

    我想在 Python 中更新 YAML 文件值 而不丢失 Python 中的格式和注释 例如我想改造 YAML 文件 value 456 nice value to value 6 nice value 界面类似于 y yaml load
  • Docker 中的 Python 日志记录

    我正在 Ubuntu Web 服务器上的 Docker 容器中测试运行 python 脚本 我正在尝试查找由 Python Logger 模块生成的日志文件 下面是我的Python脚本 import time import logging
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • pip 列出活动 virtualenv 中的全局包

    将 pip 从 1 4 x 升级到 1 5 后pip freeze输出我的全局安装 系统 软件包的列表 而不是我的 virtualenv 中安装的软件包的列表 我尝试再次降级到 1 4 但这并不能解决我的问题 这有点类似于这个问题 http
  • Python3 在 DirectX 游戏中移动鼠标

    我正在尝试构建一个在 DirectX 游戏中执行一些操作的脚本 除了移动鼠标之外 我一切都正常 是否有任何可用的模块可以移动鼠标 适用于 Windows python 3 Thanks I used pynput https pypi or
  • Python ImportError:无法导入名称 __init__.py

    我收到此错误 ImportError cannot import name life table from cdc life tables C Users tony OneDrive Documents Retirement retirem
  • 实现 XGboost 自定义目标函数

    我正在尝试使用 XGboost 实现自定义目标函数 在 R 中 但我也使用 python 所以有关 python 的任何反馈也很好 我创建了一个返回梯度和粗麻布的函数 它工作正常 但是当我尝试运行 xgb train 时它不起作用 然后 我
  • 使用for循环时如何获取前一个元素? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 循环内的上一个和下一个值 https stackoverflow com questions 1011938 python previous and next values inside
  • Pandas 每周计算重复值

    我有一个Dataframe包含按周分组的日期和 ID df date id 2022 02 07 1 3 5 4 2022 02 14 2 1 3 2022 02 21 9 10 1 2022 05 16 我想计算每周有多少 id 与上周重
  • Kivy - 单击按钮时编辑标签

    我希望 Button1 在单击时编辑标签 etykietka 但我不知道如何操作 你有什么想法吗 class Zastepstwa App def build self lista WebOps getList layout BoxLayo

随机推荐

  • 2019项目管理研讨会暨易趋(easytrack)新品发布会成功在京举办

    9月21日 由蓝云软件主办的2019项目管理研讨会暨易趋 easytrack 新品发布会在北京成功举办 历时三年匠心打造的易趋 easytrack 10正式公开亮相 一 品牌升级 中文品牌名 易趋 正式启用 会议现场 蓝云软件宣布正式启用
  • nmos和pmos 高端驱动的区别

    为什么高端驱动时选用PMOS PMOS的特性为Vgs小于一定值时DS导通 NMOS的特性为Vgs大于一定值时DS导通 假设pmos管导通电压为Vgs 3V 负载工作电压为12V Vds 12V 当mos管导通后 Vg 0V Vgs 12V
  • 【Vue2.0源码学习】内置组件篇-keep-alive

    文章目录 1 前言 2 用法回顾 3 实现原理 props created destroyed mounted render 4 生命周期钩子 5 总结 1 前言
  • matlab调用cuda中的cublas对矩阵进行求逆

    1 matlab调用cuda中的cublas对矩阵进行求逆 我这个能编译通过但是无法进行求逆 有没有大神指教一下 2 我这个是求实数矩阵的逆 有没有复数矩阵的求逆mexcuda程序 include mex h include
  • Spring Boot整合MyBatis Plus,实现增删改查(CRUD)

    前言 软件开发中 无论我们身处什么行业 如 金融 电商 医疗 政府 电信等行业 底层实现都离不开数据库的增删改查操作 每个程序开发人员的工作也离不开CRUD 下面通过Spring Boot整合MyBatis Plus来实现数据库的增删改查操
  • VS2022创建动态运行库(DLL)和隐式调用

    创建动态运行库 一 打开VS2022 新建一个DLL工程 二 在项目中新建一个头文件 输入以下代码 pragma once ifdef BUILD DLL 当源文件中有 define BUILD DLL时执行dllexport BUILD
  • 高德地图实现聚合点功能实例

    在进地图API开发时 有时会出现海量数据展示 这里就不得不使用聚合点功能 减少页面初始化过程中加载过多数据而导致卡顿现象 这里通过高德地图API为例 通过简单实例 带大家了解下聚合点实现方法 一 引入相关资源
  • 网站架构探测&chrome插件用于信息收集

    文章目录 0x01 网站架构探测 云悉 潮汐指纹 0x02 chrome插件用于信息收集 添加插件的方法 官网添加方法 开发者模式添加 Wappalyzer 下载方法 功能 FOFA Pro view 下载方法 ModHeader 0x01
  • 博客搭建二:NexT主题相关设置beta

    安装NexT 在你的博客根目录 git clone https github com iissnan hexo theme next themes next 不同版本的NexT配置文件略有不同 本次使用的是hexo theme next 7
  • 多线程(九):JUC组件

    在来时juc组件前 我们先把上一章遗漏的部分给补上 synchronized 实现策略 锁升级 无锁 gt 偏向锁 gt 轻量级锁 gt 重量级锁 还有一个 锁消除 锁消除即删除不必要的加锁操作 JVM在运行时 对一些 在代码上要求同步 但
  • sort快速排序

    sort快速排序 使用sort必须要有相应的头文件 include
  • 中标麒麟系统把玩记录

    1 指令发送邮件 echo content mail vs this is title a a sh XXX XX com 其中 content代表发送的内容 thisistitle代表邮件主题 a sh为附件 2 开机运行脚本 在etc
  • 田忌赛马java代码算法,AcWing 1489. 田忌赛马——Java版代码

    import java io import java util public class 田忌赛马 public static void main String args throws IOException BufferedReader
  • Thrift快速入门

    文章目录 Thrift的安装 windows下安装 Linux下安装 Thrift的使用 编写IDL文件 命名空间 namespace 基本数据类型 类型定义 typedef 结构体类型 struct 枚举类型 enum 异常类型 exce
  • MybatisX简介

    MybatisX简介 前言 一 什么是MybatisX 二 如何使用 1 安装插件 2 创建一个mybatis项目或者于项目中引入mybatis依赖 3 快速生成示例 3 1 快速生成mapper方法 3 2 MybatisX Genera
  • 使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异(R语言)

    使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异 R语言 箱图是一种常用的数据可视化方法 用于表示一组数据的分布特征 包括中位数 四分位数 异常值等 在比较多个模型在多个指标上的性能差异时 箱图可以提供直观的
  • NCCL相关笔记

    本文仅代表个人观点 不保证正确性 一 NCCL简介 1 什么是NCCL NCCL是NVIDIA集合通信库 NVIDIA Collective Communications Library 的简称 是用于加速多GPU之间通信的库 能够实现集合
  • #css# 【四】如何使用hover,实现父对子的样式改变?

    css 如何使用hover 实现父对子的样式改变 思路及做法 鼠标移动到父盒子的时候 里面所有的子盒子的样式都发生变化的 只需要直接在hover后面加上空格 并且加上子盒子的类名 里面再写其他样式 父盒子的类名 hover 子盒子的类名 这
  • iOS系统网络抓包方法

    原文地址 http www cnblogs com ydhliphonedev archive 2011 10 27 2226935 html 在进行iOS开发过程中 经常会遇到各种各样的网络访问问题 以前苦于没有抓包工具 很多网络问题解决
  • 【python-opencv】硬币检测

    使用 python3 8 x opencv 硬币检测 问题描述 设计思路1 使用简单特征识别 具体操作 部分代码 设计思路2 模板匹配 源码 模板制作 完整代码 问题描述 使用图像处理技术 从照片中识别硬币的个数 并判断总价值 设计思路1