入门机器视觉的正确打开方式——徒手撸一个python+opencv实现的机器视觉简易调试工具(上)

目录

  • 1.引言
  • 2.框架思路
  • 3.环境搭建
  • 4.图像处理流程化的实现
  • 5.流水线上的算法块
    • 5.1 算法块的可视化
  • 6.总结
  • 7.调试工具成品链接
  • PS.扩展阅读
    • ps1.六自由度机器人相关文章资源
    • ps2.四轴机器相关文章资源
    • ps3.移动小车相关文章资源

1.引言

在当今AI时代,关于视觉识别似乎已被深度学习所统治,而深度学习是个黑箱,无法看到里面运行的机制,并且它是一个疯狂的吞大数据的野兽,且运行需要极高的CPU或GPU的配置,对于初学者,尤其是手上没有高配置的机器的人,进入视觉识别设置了一道高高的门栏。
机器视觉作为人工智能领域的一个重要分支,正逐渐渗透到工业自动化、智能监控、医疗诊断、自动驾驶等众多领域。机器视觉技术赋予了机器“看”的能力,使得机器能够感知环境、理解图像内容,并做出相应的决策。
对于初学者来说,入门机器视觉可能会感到无从下手,市面上虽然有许多成熟的机器视觉软件,但它们往往价格昂贵,且功能复杂,不够灵活。幸运的是,Python语言以其简洁易懂的特性,结合OpenCV这一强大的计算机视觉库,为初学者提供了一个低成本、高效率的学习平台。
在这里插入图片描述

本文将引导读者通过编写一个简易的机器视觉调试工具,来深入理解机器视觉的基本概念和操作流程。我们将从零开始,一步步构建一个基于Python和OpenCV的应用程序,不仅能够帮助初学者快速入门,还能作为进一步探索机器视觉领域的知识储备。
效果如下:
在这里插入图片描述

2.框架思路

如上所示,我们可以把opencv这个极开源世界优秀视觉处理的知识库,从抽象的代码,变成一条条流程化的知识流,并且利用将超级参数的调整可视化,即视化实现对机器视觉处理模块或算法的快速直观理解,极端时间内建立对算法的“手感”。便于在实际问题中,快速思考获得解决方案。
视觉识别的过程就是一个图像信息的流处理过程:
在这里插入图片描述
基于以上思考,可以把我们的调试工具设计成一个类似流水线一样的解读执行过程,就是我们先根据场景特点确定上下游的处理模块,把它们做成一个草图,然后我们的主程序负责把它按流程图执行,并且可以随时打开流水线的某个处理盒子,对参数进行方便的调节。总得来说这个工具应该是这样的:
在这里插入图片描述

3.环境搭建

python的环境搭建是个头疼的过程,主要障碍是版本的选择,和网速。只要确定好这两者,那么也是一两行指令的事情。裸跑python的基本流程如下(有IDE工具跳过):
在这里插入图片描述

以上流程用到的指令有:

#windows
#更换成国内源
pip config set global index-url https://pypi.tuna.tsinghua.edu.cn/simple
#创建虚拟环境:
python -m venv myenv
#进入虚拟环境
myenv\Scripts\activate
#进入项目路径:
cd projectdir
#安装依赖:
pip install -r requirements.txt

#指令安装
sudo apt-get update 
sudo apt-get install python3
#更换成国内源
pip config set global index-url https://pypi.tuna.tsinghua.edu.cn/simple
#创建虚拟环境:
python3 -m venv myenv
#进入虚拟环境
source myenv/bin/activate
#进入项目路径:
cd projectdir
#安装依赖:
pip install -r requirements.txt

本项目用到的库:

matplotlib==3.8.4
networkx==2.6.3
numpy==1.22.4
opencv_python==4.7.0.68
pillow==10.3.0
PySimpleGUI==4.60.5
scikit_learn==1.5.0

4.图像处理流程化的实现

自然而然我们想到了一些优秀的数据结构可以实现我们的思路,比如xml、json。在python中我们就自然而然用到了字典这种格式:

{  
            "@img_source":["图像源1"],
            "@folder":'./image',           
            "图像源1":{
                    "funname":"image_source",
                    "path":["./image/mask.png"],
                    "output":[],
                    "result":[],
                    "father":["root"],
                    "son":["颜色选择1","腐蚀操作1","固定阈值分割1","canny边缘1","颜色聚类1","图像旋转1"],   
                    },
 
            "图像旋转1":{
                    "funname":"imgrotaionTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":[],      
                    },
            "canny边缘1":{
                    "funname":"CannyThresholdTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":["形态学1"],                    
                    },
            "颜色聚类1":{
                    "funname":"KmeansThresholdTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":[],                    
                    },
            "形态学1":{
                    "funname":"morphologyTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["canny边缘1"],
                    "son":["查找轮廓11"],                    
                    },
            "查找轮廓11":{
                    "funname":"findContoursTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["形态学1"],
                    "son":[]                    
                    },           
            
            
            "颜色选择1":{
                    "funname":"color_filterTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":["阈值分割111"],                    
                    },
            "阈值分割111":{
                    "funname":"thresholdTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["颜色选择1"],
                    "son":["形态学111"],
                    },
             "形态学111":{
                    "funname":"morphologyTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["阈值分割111"],
                    "son":["查找轮廓111"],                    
                    },
             "查找轮廓111":{
                    "funname":"findContoursTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["形态学111"],
                    "son":[]                    
                    },        
                    

            "腐蚀操作1":{
                    "funname":"erodeTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":[]   
                    
                    },
            "固定阈值分割1":{
                    "funname":"thresholdTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":["形态学11"]   
                    
                    },
            "形态学11":{
                    "funname":"morphologyTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["固定阈值分割1"],
                    "son":["查找轮廓1"],                    
                    },
 
            "自适阈值分割1":{
                    "funname":"adaptiveThresholdTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["图像源1"],
                    "son":[]   
                    
                    },
            
            "查找轮廓1":{
                    "funname":"findContoursTH",
                    "output":[],
                    "result":[],
                    "args":[],
                    "father":["形态学11"],
                    "son":[]                    
                    },            

            } 

如上通过这种简洁的数据格式,我们一口气把6条图像处理流水线給绘制了出来:
在这里插入图片描述
根据这样的思路,我们可以根据需要绘制无数条!!!

5.流水线上的算法块

一条流水线由一个一个处理块组成,处理块对于初学者来说无需自己从0开始编代码,opencv已经几乎集成了所有视觉处理算法块,并且是开源的,直接拿过来用就可以,而这块达到会使用的一个衡量指标是,对算法块参数的理解,难点也在这里。而理解算法块参数的最快方法不是去阅读计算机视觉原理,而是调试,就像想学会游泳最快的方法是跳进水里亲自感觉。后面如果再想深入,那么花时间去啃计算机视觉原理也不迟。
在这里插入图片描述
如上所示,一个查找颜色的模块,如果用opencv提供的算法块直接用代码形式去使用,那么要找到一中需要的颜色,在纯代码中,相信你会在确定模式、参数的设置中迷失,直至怀疑人生。但是如果将算法块中的参数暴露,并采用滑块进行随意调节,相信一个5岁的小孩也马上能掌握这个算法的参数调节和模式选择。
需要指出的是,在一个简单的机器视觉任务中,颜色查找这种古老的算法,仍然不失为一种性价比高的解决方案,还要什么AI、和GPU呢?

5.1 算法块的可视化

这里所谓的可视化,就是把算法模块套上一个GUI的皮囊,把参数暴露出来,供人们肆意玩弄。直到摸清它的脾气为止。这里我们用了简单办法,例如一个图像的旋转算法模块:

def imgrotaion(inputimg,center,angle,ratio=1,dsize=None,flags=None,borderMode=cv2.BORDER_REFLECT,borderValue=(0,0,0)):
    """
    getRotationMatrix2D中:
    center-旋转中心(x,y)
    angle-旋转角度
    ratio-缩放比例    
    
    warpAffine其中:
    src - 输入图像。
    M - 变换矩阵。
    dsize - 输出图像的大小。
    flags - 插值方法的组合(int 类型!)
    默认为 flags=cv2.INTER_LINEAR,表示线性插值,此外还有:cv2.INTER_NEAREST(最近邻插值)   cv2.INTER_AREA (区域插值)  cv2.INTER_CUBIC(三次样条插值)    cv2.INTER_LANCZOS4(Lanczos插值)
    borderMode - 边界像素模式(int 类型!)
    
    borderValue - (重点!)边界填充值; 默认情况下,它为0.    
    """
    if len(inputimg.shape)==3:        
        if dsize==None:
            h= inputimg.shape[0]
            w= inputimg.shape[1]
            dsize=(w,h)
        if flags==None:
            flags=cv2.INTER_LINEAR
        M = cv2.getRotationMatrix2D(center, angle, ratio)
        dst=cv2.warpAffine(inputimg,M,dsize,flags=flags,borderMode=borderMode,borderValue=borderValue)
        return True,dst
    else:
        print("wrong image shape")
        return False,inputimg 

def imgrotaionTH(inputimg,mblock):
    """
    图像旋转
    """
    x=inputimg.shape[1]
    y=inputimg.shape[0]
    layout= [ 
        [sg.Text('刷新率',size=(15, 1)),sg.Slider((1, 10),1 , 1, orientation='h', size=(10, 15), key='-speed-'),sg.Button('刷新')],
        [sg.Button('Exit')],
         [sg.Text('旋转角度:',size=(5, 1)),sg.Slider((1, 360),90, 1, orientation='h', size=(10, 15), key='-angle-')
         ],
         [sg.Text('缩放比例:',size=(5, 1)),sg.Slider((0.1, 10),1, 0.1, orientation='h', size=(10, 15), key='-ratio-')],
         [sg.Text('旋转中心:(x,y)',size=(5, 1)),
          sg.InputText('('+str(int(x/2))+","+str(int(y/2))+")",key='-center-',size=(10, 1))],
         [sg.Text('填充颜色',size=(15, 1)),
          sg.InputText('(0,0,0)',key='-bordcolor-',size=(10, 1))],             
         [sg.Image(filename='', key='-IMAGE-')],            
        ]
    win = sg.Window('图像旋转TH', layout,resizable=True,disable_close=True)
    def flash(win): 
        win_active=True
        event=True
        maxtime=1
        tita=0
        while win_active:
            #...略
            
            if event is None or event == 'Exit':
                win.close()
                win_active = False                                        
                break 
    flash(win) 

如上,我们在imgrotaion函数块下面又建立了一个imgrotaionTH的GUI,并且把所有所需的参数显示出来,这样就完成了算法从抽象到形象。

6.总结

本上篇就到这里了,主要阐述了一些进入机器觉的法门,和一个我们认为比较实用的小工具的创建基本思想。
在这里插入图片描述

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

下篇接着唠…

7.调试工具成品链接

已经做了一个开箱即用的Windows的exe程序,供玩弄,本站资源:下载链接

-------------本篇完-------------

————————————————————————————————————————

PS.扩展阅读

————————————————————————————————————————

对于python机器人编程感兴趣的小伙伴,可以进入如下链接阅读相关咨询

ps1.六自由度机器人相关文章资源

(1) 对六自由度机械臂的运动控制及python实现(附源码)
在这里插入图片描述

(2) N轴机械臂的MDH正向建模,及python算法
在这里插入图片描述

ps2.四轴机器相关文章资源

(1)python机器人实战——0到1创建一个自动是色块机器人项目-CSDN直播
(2)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(4)实现了语音输入+大模型指令解析+机器视觉+机械臂流程打通
在这里插入图片描述

ps3.移动小车相关文章资源

(1)python做了一个极简的栅格地图行走机器人,到底能干啥?[第五弹]——解锁蒙特卡洛定位功能-CSDN博客
(2) 对应python资源:源码地址
在这里插入图片描述

(3)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(上篇)_agv编程-CSDN博客
(4)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)_agv路线规划原则python-CSDN博客
对应python及仿真环境资源:源码链接
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

位运算算法:编程世界中的魔法符号

✨✨✨学习的道路很枯燥,希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一. 常见位运算总结 二、常见位运算题目 2.1 位1的个数 2.2 比特数记位(典型dp) 2.3 汉明距离 2.4 只出现一次的数字(1) 2.5 只出…

QtScrcpy最出色的C++开源手机投屏控制软件

QtScrcpy是一款开源的跨平台屏幕录制和投屏工具 基本概述: 它基于Android的ADB(Android Debug Bridge)和Electron框架,为用户提供了简洁且功能强大的用户界面。 支持平台: QtScrcpy支持Windows、macOS和Linux三大…

算力与能源正在成为世界的硬通货,看超级计算机安腾如何突围

特斯拉创始人马斯克公开表态称未来两年人工智能行业将由“缺硅”变为“缺电”。据媒体报道,OpenAI的ChatGPT每天消耗超过50万千瓦时的电力,用于处理约2亿个用户请求,相当于美国家庭每天用电量的1.7万多倍。除了这类生成式AI耗能外&#xff0c…

【Linux】使用 iptables 验证访问HDFS 所使用到的端口

目录 ​编辑 一、实操背景 二、iptables 简介 三、模拟操作 一、实操背景 背景: 在客户有外网的服务器需要访问内网大数据集群HDFS,使用iptable模拟测试需要开放的端口。 二、iptables 简介 具体介绍看文章: 【Linux】Iptables 详解与实战…

Elasticsearch出现Connection reset by peer

Elasticsearch出现Connection reset by peer分析 1.异常: 2024-06-13 13:17:10.539 WARN [http-nio-30411-exec-9]com.longdaotech.config.ESConfig -onFailure node:[hosthttp://192.168.239.253:9200] 2024/6/13 13:17:10 2024-06-13 13:17:10.541 WARN [http-n…

aop注解快速实现数据脱敏返回

说明: 公司之前数据接口数据管理不严格,很多接口的敏感数据都没有脱敏处理,直接返回给前端了,然后被甲方的第三方安全漏洞扫出来,老板要求紧急处理,常用的话在单个字段上加上脱敏注解会更加的灵活&#xf…

Win11升级24H2出现绿屏怎么办?这些方法帮你解决!

在Win11电脑操作中,用户为了体验24H2版本推出的新功能,所以要把系统版本升级为24H2版本。但升级过程中电脑却出现了绿屏问题,不清楚要怎么操作才能解决绿屏的问题?接下来小编给大家分享几种简单有效的解决方法,让大家能…

轨迹优化 | 图解欧氏距离场与梯度场算法(附ROS C++/Python实现)

目录 0 专栏介绍1 什么是距离场?2 欧氏距离场计算原理3 双线性插值与欧式梯度场4 仿真实现4.1 ROS C实现4.2 Python实现 0 专栏介绍 🔥课程设计、毕业设计、创新竞赛、学术研究必备!本专栏涉及更高阶的运动规划算法实战:曲线生成…

基于Java和SSM框架的多人命题系统

你好呀,我是计算机学长猫哥!如果你对多人命题系统感兴趣或者有相关开发需求,文末可以找到我的联系方式。 开发语言:Java 数据库:MySQL 技术:Java SSM框架 工具:Eclipse、MySQL Workbench、…

大众点评_token,mtgsig

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许可禁止转载&#xff0…

springboot“漫画之家”系统 LW+PPT+源码

3 系统分析 链接:https://pan.baidu.com/s/1ihILTui-XEFdC15mcOB0vA?pwdewry 提取码:ewry 3.1系统可行性分析 3.1.1经济可行性 由于本系统是作为毕业设计系统,且系统本身存在一些技术层面的缺陷,并不能直接用于商业用途&#xf…

用PHP来调用API给自己定制一个“每日新闻”

头条新闻汇聚了互联网上的时事动态,提供最新新闻动态、网络热门话题和视频更新等,覆盖社会、政治、体育、经济、娱乐、科技等多个领域,并不断刷新内容。企业应用这一接口后,可以快速吸引更多的用户访问自己的平台。即使是非新闻类…

直播预告丨华为数字化转型解决方案,助力钢铁行业飞越“寒冬”!

我国钢铁行业整体盈利处于近年来较低水平。2024年一季度,钢铁企业累计营业收入为1.49万亿元,同比下降4.55%;利润总额为87.08亿元,同比下降47.91%;平均利润率为0.58%,同比下降0.49%。 行业发展正面临着诸多…

【NOI-题解】1389 - 数据分析1750 - 有0的数1457 - 子数整除1121 - “倒”数1962. 数值计算

文章目录 一、前言二、问题问题:1389 - 数据分析问题:1750 - 有0的数问题:1457 - 子数整除问题:1121 - “倒”数问题:1962. 数值计算 三、感谢 一、前言 本章节主要对循环中带余除法部分题目进行讲解,包括…

【图解IO与Netty系列】Netty源码解析——服务端启动

Netty源码解析——服务端启动 Netty案例复习Netty原理复习Netty服务端启动源码解析bind(int)initAndRegister()channelFactory.newChannel()init(channel)config().group().register(channel)startThread()run()register0(ChannelPromise promise)doBind0(...) 今天我们一起来学…

数据价值管理-数据使用标准

前情提要:数据价值管理是指通过一系列管理策略和技术手段,帮助企业把庞大的、无序的、低价值的数据资源转变为高价值密度的数据资产的过程,即数据治理和价值变现。第一讲介绍了业务架构设计的基本逻辑和思路。 前面我们讲完了数据资产建设标准…

线性卷积(相关)和圆周卷积(相关)以及FFT之间的关系(AEC举例)

时域自适应滤波算法中的线性卷积和线性相关运算量较大,导致计算复杂度升高,我们更愿意把这两个信号变换到频域,通过频域相乘的方式来取代时域复杂度相当高的卷积或相关运算。 预备知识:线性卷积(相关)和圆…

Origin中增加一列并更新绘图

一、在book当中增加数据列 二、回到绘图中,双击图层 三、修改增加图像的格式 四、根据需要删除图例中多余的部分

Stable Diffusion 有什么推荐的Checkpoint 模型、Lora?

引言 -2k字给讲清楚我最常用的SD模型库、关键词和参数! 2022年末我接触sd的时候,还在为可以用Ai绘画而沾沾自喜,现在玩的风生水起,真的感觉没有白接触。除了chatgpt的出现,Ai绘画无意识这两年来的黑科技,如…