算法部分---烟柱数量检测

文章目录

  • 摘要
  • 一、光学成像
  • 二、图像处理
    • 1.获取烟柱区域
    • 2.边界区域填充
    • 3.二值化
    • 4.形态学后处理
    • 5.数量计算
  • 总结

摘要

传统方法检测烟柱的数量

一、光学成像

盛放烟支的烟盒尺寸大致是1000mm*1000mm,穹顶光暂时无法覆盖该尺寸,现场采用4根条形光源分布在烟盒的四周做均匀光照射眼烟盒,采用分辨率为2592*1944的500万像素的灰度灰度相机

二、图像处理

1. 获取烟柱区域

1.1 原始图像如下所示:

1.2 烟柱的mask区域如下所示:

#3. getMaskImg
def getRoughBinImg(srcImg, grayVal):
    ret, dst = cv2.threshold(srcImg, grayVal, 255, cv2.THRESH_BINARY)#固定阈值二值化
    window = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))    #开操作
    maskBinImg = cv2.morphologyEx(dst, cv2.MORPH_OPEN, window, iterations = 2)
    bitMaskImg = cv2.bitwise_and(srcImg, srcImg, mask =maskBinImg)   #roi的烟柱区域
    return bitMaskImg, maskBinImg

2. 边界区域填充

2.1 测量数量的二值化图像采用动态二值化方法,因此在边界处的区域需要填充,否则会造成边界区域的图像是联通的,中间区域即使是分散的,如下图所示。

2.2 在边缘出的图形填充中心的图像。

#边界填充的中心image
def getEdgeFillImg(roiImg, maskBinImg):
    #1. 大致的起始坐标
    rectPos = getBoundRectPos(maskBinImg)
    #2. 中心的rect
    centRectImg = getScaleRoiImg(roiImg, rectPos)
    #3. blackMask的填充
    edgeFillImg = getEdgeImg(roiImg, maskBinImg, centRectImg)
    return edgeFillImg

3. 二值化

动态二值化的两个关键参数,一个是滑动窗口,即邻域内像素的加权和,采用的是高斯还是均值。另一个参数是加权值减去这个常数。

#binImg的
def getSrcBinImg(roiImg, edgeFillImg, widowSize, constVal):
    srcAddImg = cv2.addWeighted(roiImg, 1, edgeFillImg, 1, 0)
    binImg = getSubBinImg(srcAddImg, widowSize, constVal)
    return binImg

#adaptBin
def getSubBinImg(roiImg, widowSize, constVal):
    binSizeTmp = 2*widowSize + 1      #20
    binConstTmp = constVal - 50       #48
    srcBinImg = cv2.adaptiveThreshold(roiImg, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,         
                cv2.THRESH_BINARY, binSizeTmp, binConstTmp)
    return srcBinImg

4. 形态学后处理

部分烟柱有粘连,采用形态学后处理,进行行和列的分割, 分割后的效果如下所示。

#形态学
def getDstBinMorph(srcBinImg):
    #总体2*2
    window = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
    dstBinImg = cv2.morphologyEx(srcBinImg, cv2.MORPH_OPEN, window, iterations = 1)
    #行和列的分割
    windowRow = cv2.getStructuringElement(cv2.MORPH_RECT, (6, 1))
    windowLine = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 6))
    dstBinImg1 = cv2.morphologyEx(dstBinImg, cv2.MORPH_OPEN, windowRow, iterations     
                 = 1)
    dstBinImg2 = cv2.morphologyEx(dstBinImg1, cv2.MORPH_OPEN, windowLine, 
                 iterations = 1)
    return dstBinImg2

5. 数量计算

代码:

#7. 近似的轮廓
def findBinRects(binImg):
    allContours, _ = cv2.findContours(binImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if len(allContours) ==0:
        print("error not find the contour pos")
        return False
    #计算轮廓面积
    centPointList = []
    contours = sorted(allContours, key = cv2.contourArea, reverse = True)
    for subCount in contours:
        subCountFlag, centPoint = getCheckCount(subCount)
        if subCountFlag:
            centPointList.append(centPoint)
        
    return True, centPointList

 


总结

二值化图像,形态学后处理,注意边际的区域。

采用分割网络,如unet虽然稳定,但是标注花费较多人工成本,同时网络推倒时间较长。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值