【python-opencv】硬币检测

这篇具有很好参考价值的文章主要介绍了【python-opencv】硬币检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用 python3.8.x,opencv

问题描述

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

设计思路1

使用简单特征识别

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

具体操作

  1. 将图片转换为HSV颜色模型
    图像识别硬币,图像处理,opencv,计算机视觉,python
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

图像识别硬币,图像处理,opencv,计算机视觉,python

部分代码

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. 选取最优匹配
    图像识别硬币,图像处理,opencv,计算机视觉,python

源码

模板制作

有同学说不知道如何制作模板,其实,只需要将上面所说的模板匹配过程执行一半,获取到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文章来源地址https://www.toymoban.com/news/detail-786749.html

到了这里,关于【python-opencv】硬币检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python-OpenCV中的图像处理-图像阀值

    与名字一样,这种方法非常简单。但像素值高于阈值时,我们给这个像素赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。这个函数就是 cv2.threshhold()。这个函数的第一个参数就是原图像,原图像应该是灰度图。第二个参数就是用来对像素值进

    2024年02月13日
    浏览(31)
  • Python-Opencv图像处理的小坑

            最近在做一点图像处理的事情,在做处理时的cv2遇到一些小坑,希望大家遇到的相关的问题可以注意!!           cv2.imwrite(filename, img, [params]) filename :需要写入的文件名,包括路径和文件名,以及期望的扩展名(例如,.jpg,.png,.bmp等)。 img :需要保存的

    2024年02月04日
    浏览(40)
  • Python-OpenCV中的图像处理-图像直方图

    通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值( 0 到 255), y 轴是图片中具有同一个灰度的点的数目。 BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到255,你就需要 256 个数来显示上面的直方图。但是,如果你不需

    2024年02月12日
    浏览(44)
  • Python-OpenCV中的图像处理-图像金字塔

    同一图像的不同分辨率的子图集合,如果把最大的图像放在底部,最小的放在顶部,看起来像一座金字塔,故而得名图像金字塔。 cv2.pyrUp():上采样 cv2.pyrDown():下采样 高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图

    2024年02月13日
    浏览(42)
  • Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之四 简单行人人体检测效果

    目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之四 简单行人人体检测效果 一、简单介绍 二、简单行人人体检测效果实现原理 三、简单行人人体检测效果案例实现简单步骤 四、注意事项 Python是一种跨平台的计算机程序设计语言。是一种面向对

    2024年04月26日
    浏览(36)
  • Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别

    目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别 一、简单介绍 二、简单进行人脸训练与识别 1、LBPH(Local Binary Patterns Histograms)算法进行人脸训练和识别 2、实现步骤: 3、判断是谁的人脸: 案例中涉及的关键函数说

    2024年04月26日
    浏览(62)
  • Python-OpenCV中的图像处理-物体跟踪

    现在我们知道怎样将一幅图像从 BGR 转换到 HSV 了,我们可以利用这一点来提取带有某个特定颜色的物体。在 HSV 颜色空间中要比在 BGR 空间中更容易表示一个特定颜色。在我们的程序中,我们要提取的是一个蓝色的物体。下面就是就是我们要做的几步: • 从视频中获取每一帧

    2024年02月13日
    浏览(38)
  • Python-OpenCV中的图像处理-几何变换

    对图像进行各种几个变换,例如移动,旋转,仿射变换等。 cv2.resize() cv2.INTER_AREA v2.INTER_CUBIC v2.INTER_LINEAR res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) 或 height, width = img.shape[:2] res = cv2.resize(img, (2 width, 2 height), interpolation=cv2.INTER_CUBIC) OpenCV提供了使用函数cv2.warpAffine()实

    2024年02月13日
    浏览(55)
  • Python-OpenCV中的图像处理-霍夫变换

    霍夫(Hough)变换在检测各种形状的技术中非常流行,如果要检测的形状可以用数学表达式描述,就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使用。 Hough直线变换,可以检测一张图像中的直线 cv2.HoughLines(image, rho, theta, threshold) return:返回值

    2024年02月13日
    浏览(35)
  • Python-OpenCV中的图像处理-直方图

    通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值( 0 到 255), y 轴是图片中具有同一个灰度的点的数目。 BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到255,你就需要 256 个数来显示上面的直方图。但是,如果你不需

    2024年02月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包