二值图像分析案例精选

说起来,我还是挺惭愧的,去年四月份连续在51CTO博客发表了一波技术文章,后来因为自己太忙就慢慢忘记更新拉,前两天一看访问量居然突破100+万拉,感谢各位的厚爱与支持,更觉得51CTO博客改版之后真的是很棒!所以又来更新了!

最近一直有人向我提问很多二值图像分析相关的问题,特别选择了两个典型的轮廓分析问题。进行分析与编码实现与演示,废话不多说,先看第一个问题。

问题一

问题描述如下

想找到工具盘中间缺少的几个点,统计出可以看到的工件数目

仔细分析图像发现,中间都毫无另外的有个白色很亮的圆圈,这个给了我两个思路

  • 可以通过霍夫变换检测圆来提取到
  • 可以通过二值图像分析来提取 + 轮廓分析来提取到这些点

得到这些轮廓点之后通过分析整个轮廓区域得到倾斜角度,进行纠偏,然后通过X与Y投影进行分割,得到每个零件的中心位置坐标,根据每一行的间隔设置阈值,从而实现缺少部分部分的标出与件数统计,确定了这样的思路以后,我就开始了写代码。代码实现是基于轮廓分析的思路,因为这个方法,用的阈值比较少,有利于算法稳定性检测。演示各部输出。二值化处理之后(形态学处理):

轮廓发现与校正角度之后

投影分析与统计结果如下

此外基于霍夫也是可以尝试的,霍夫的二值化效果也比较好,显示如下:

感兴趣的同学可以自己继续尝试下去。

问题二

描述如下:

如何统计下图中的对象个数,原图如下


看到这个图像之后,个人觉得解决十分简单,基于最外层轮廓发现即可,无需树形结构与层次分析,集合图像形态学分析或者距离变换就可以得到,最终代码的运行结果如下:

代码

问题1的代码如下(已经添加各步骤注释了):

src = cv.imread("D:/images/zsxq/zsxq_01.jpg")
cv.imshow("input", src)

# 二值化处理
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, se)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_OTSU | cv.THRESH_BINARY)

# 形态学处理
se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, se)
se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (10, 10))
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se)
cv.imshow("binary", binary)

# 轮廓分析
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
result = np.zeros_like(binary)
total = 0
for cnt in range(len(contours)):
    area = cv.contourArea(contours[cnt])
    if area < 55:
        continue
    rrt = cv.minAreaRect(contours[cnt])
    cx, cy = rrt[0]
    cv.circle(result, (np.int32(cx), np.int32(cy)), 5, (255), -1)
    total += 1

# 几何纠偏
h, w = result.shape
pts = []
for row in range(h):
    for col in range(w):
        pv = result[row, col]
        if pv == 255:
            pts.append((col, row))

pts = np.array(pts)
rrt = cv.minAreaRect(pts)
print(rrt)
M = cv.getRotationMatrix2D(((w-1)/2.0,(h-1)/2.0),rrt[2],1)
dst = cv.warpAffine(result,M,(w,h))
src = cv.warpAffine(src,M,(w,h))

# Y方向投影
tbins = y_split(dst)

# X 方向投影
print("y-step", tbins)
for i in range(0, len(tbins), 1):
    if i == 0:
        roi = dst[0:tbins[i], 0:w]
        src_roi = src[0:tbins[i], 0:w, :]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)
    if i == len(tbins)-1:
        roi = dst[tbins[i]:h-1, 0:w]
        src_roi = src[tbins[i]:h-1, 0:w, :]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)
    if 0 < i < (len(tbins)-1):
        roi = dst[tbins[i-1]:tbins[i] - 1, 0:w]
        src_roi = src[tbins[i-1]:tbins[i] - 1, 0:w,:]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)

# 显示结果
cv.imshow("result", result)
cv.imshow("dst", dst)
cv.putText(src, "numbers: " + str(total), (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2)
cv.imshow("detection", src)

cv.waitKey(0)
cv.destroyAllWindows()

问题二:

import cv2 as cv
import numpy as np

src = cv.imread("D:/images/zsxq/zsxq_02.jpg")
cv.imshow("input", src)
src = cv.GaussianBlur(src, (3, 3), 0)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
edge = cv.Canny(src, 50, 100)

se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (10, 10))
binary = cv.morphologyEx(edge, cv.MORPH_CLOSE, se)
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
for cnt in range(len(contours)):
    area = cv.contourArea(contours[cnt])
    if area < 100:
        continue
    count += 1
    rrt = cv.minAreaRect(contours[cnt])

    # rotated rectangle
    box = cv.boxPoints(rrt)
    box = np.intp(box)
    cv.drawContours(src, [box], 0, (255, 0, 0), 2)

cv.imshow("binary", binary)
cv.imshow("result", src)
cv.waitKey(0)
cv.destroyAllWindows()

解锁更多图像处理与视频分析技能,
欢迎学习我的最新OpenCV4图像处理与视频分析视频课程

OpenCV4图像处理与视频分析 - 实战教程

感谢大家关注我的博客,我会继续更新!
有你们有动力!

原文地址:https://blog.51cto.com/gloomyfish/2407387

时间: 2024-11-09 06:13:01

二值图像分析案例精选的相关文章

Spark学习四:网站日志分析案例

Spark学习四:网站日志分析案例 标签(空格分隔): Spark Spark学习四网站日志分析案例 一创建maven工程 二创建模板 三日志分析案例 一,创建maven工程 1,执行maven命令创建工程 mvn archetype:generate -DarchetypeGroupId=org.scala-tools.archetypes -DarchetypeArtifactId=scala-archetype-simple -DremoteRepositories=http://scal

机器学习 - 文本分析案例 - 新闻分析

文本分析概念 停用词 语料中大量出现, 无用数据, 如下类似的这种词语 Tf  - 词频统计 TF 的计算方式有很多, 最常见的用 某词文章中出现次数 / 文章总词数 idf  - 逆文档频率 TF - idf   关键词提取 相似度 分词 语料库 词频 词频向量 整体流程 语料清洗 (去掉停用词, 去掉大量重复的非正常用语等) 计算公式 文本分析案例 - 新闻分析 样本数据 数据来源于 搜狗实验室新闻数据   数据需要处理成  pandas 便于读取的数据才可以使用 import pandas

MongoDB涉及的业务比较慢--慢查询优化分析案例--以及参数说明

描述:该优化案例是想表达要了解各个参数的含义,结合业务的分析以及逻辑实现.以及创建索引和列顺序是如何选择的等(这里不再叙述) 环境描述一下: MongoDB版本 3.0.9,副本集3节点,内存64G,cpu 16 core,磁盘2TB SSD,使用WT存储引擎... 该表数据量2.6亿多. 大致分析如下: 通过mloginfo统计查看日志中慢查询的分类(将生产系统日志scp到测试服务器做的) # mloginfo --queries mongod.log-20160427 namespace  

android 性能分析案例

本章以实际案例分析在android开发中,性能方面的优化和处理.设计到知识点有弱引用,memory monitor,Allocation Tracker和leakcanary插件. 1.测试demo 下载bug项目:https://github.com/lzyzsd/MemoryBugs,请注意配合使用MemoryMonitor, AllocationTracker以及HeapDump,LeakCanary等工具来查找潜在的内存问题,并尝试解决. 2.测试工具介绍 (1)memory monit

比“啤酒尿布”更好的关联分析案例

一东北人养了一只鸡和一头猪.一天鸡问猪:"主人呢?"猪说:"出去买蘑菇了."鸡听了撒丫子就跑.猪说:"你跑什么?"鸡叫道:“有本事主人买粉条的时候你小子别跑!" 在此之前,提到关联分析,被引用最多的案例莫过于“啤酒与尿布”的故事,不过我想有了“猪肉炖粉条”这个案例后,啤酒与尿布要退出历史舞台了. 补课:啤酒与尿布 在美国有婴儿的家庭中,一般是母亲在家中照看婴儿,年轻的父亲前去超市购买尿布.父亲在购买尿布的同时,往往会顺便为自己购买啤酒,这样就会出现啤酒与尿布这两件看上去不相干的商品经常会出现在同

Linux下的CPU性能瓶颈分析案例

问题描述: 在对notify执行性能测试时发现cpu负载突然飙高,cpu利用率高达95%.这时候就要排查是哪些线程消耗了cpu,并从代码层找到占用cpu的“罪魁祸首”. 步骤: 1. 先用ps+grep找到被测试的进程pid. 比如:ps –ef|grep notify,得到pid为29128. 2. 执行top -H -p,可显示出该进程下的所有线程.找到占用cpu最多的子线程pid,并将其转换为16进制. 比如:top -H -p 29128,看到notify的所有子线程.其中,%CPU 比

因为diagwait未配置导致RAC脑裂日志记录不完整的分析案例

1.故障现象 一个RAC,CRS版本为10.2.0.4,在第二节点DOWN机后,第一节点也相继DOWN机. 2.CRS日志分析 2.1 二节点日志情况 CRS_LOG [cssd(8796)]CRS-1611:node XXdb1 (1) at 75% heartbeat fatal, eviction in 14.118 seconds 2014-07-04 22:49:38.556 [cssd(8796)]CRS-1611:node XXdb1 (1) at 75% heartbeat fa

分析案例:应用服务器W3WP进程CPU持续超过百分之九十(Oracle客户端Bug)

问题描述: 项目反馈应用负载的其中一台服务器业务操作的响应非常慢,登录该服务器发现W3WP进程CPU持续超过90%,哪怕在业务低峰期也是如此?远程查看后发现该应用服务器承载的请求确实很低,why??? 原因分析: 抓取w3wp进程的dump发现,正在运行的线程都没有我们系统的堆栈代码.并且长时间运行的工作线程的栈顶基本都是Oracle.DataAccess.Client.OracleTuningAgent.DoScan() ---->Oracle.DataAccess.Client.Oracle

分析案例:界面提示“基础链接已经关闭:接收时发生错误”----本质为StackOverflow

问题描述: 一个业务复杂.执行时间很长的功能,经常报出“基础链接已经关闭:接收时发生错误”,很是蹊跷... 问题分析: 首先,查阅应用服务器的系统日志,发现问题发生时总是会伴随着w3wp进程崩溃的错误,很有问题呀... 错误存储段 ,类型 0 事件名称: APPCRASH 响应: 不可用 Cab Id: 0 问题签名: P1: w3wp.exe P2: 7.5.7601.17514 P3: 4ce7afa2 P4: oracommon11.dll P5: 11.2.0.3 P6: 4eb215c