opencv人脸识别以及自定义物体识别系统

article/2025/9/11 19:39:27

目录

一、简介:

二、软硬件应用:

三、模块介绍:

(一)人脸识别:

 (二)、自定义物体识别:

(三)、图片展示:

(四)、python框架:

(五)、执行器--单片机:

四、效果展示:

五、总结 :


 

一、简介:

        现如今机器视觉的应用可谓是遍地开花,人脸识别更可谓是随处可见。opencv作为视觉库被普遍应用,此项目正是基于opencv设计的一个既可以识别人脸也可以识别自定义物体的系统。

二、软硬件应用:

pycharm(python版本3.10)

opencv-contrib-python()

opencv3.4.8(这个自带训练分类器的exe--opencv_createsamples.exe,opencv_traincascade.exe)

kile5

正点原子STM32F103mini

pc(在我的笔记本进行项目)

摄像头(我的笔记本上没有内置摄像头,所以用了一个外置摄像头)

三、模块介绍:

(一)人脸识别:

        这个项目中我分别体验了face_recognition和opencv自带的Haar特征分类器。

        对于face_recognition:单个人的时候face_recognition准确度很可靠,但是有一个明显的缺点就是太慢(可能是我代码的问题),检测的帧率只有3次/秒。如果检测多个人,并且两个人很相似时准确度就有点说不过去了(血和泪的经历,项目写到一半发现实在太慢,才决定狼狈地重写人脸识别代码)。

        对于opencv自带的Haar特征分类器:准确度虽不如face_recognition但还可以,他的速度很快,我的摄像头时30帧的,它检测的帧率可以达到20次/秒(我已经感到满足了)

       人脸识别部分使用了opencv自带的Haar特征分类器--haarcascade_frontalface_alt2.xml ,相较于其他几个,这个我感觉很好。下面是我的代码,

check_time=0
def face_Detector(img,ser):gary=cv.cvtColor(img,cv.COLOR_BGR2GRAY)face_detect=cv.CascadeClassifier('C:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')#haarcascade_frontalface_default.xmlface=face_detect.detectMultiScale(gary,1.1,5,cv.CASCADE_SCALE_IMAGE,(100,100),(300,300))for x,y,w,h in face:cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)ids,confidence = recognizer.predict(gary[y:y+h,x:x+w])if confidence<80:global check_timecheck_time += 1if check_time > 36:check_time = 0# save人员信息save(name[ids-1])ser.write('1'.encode())cv.putText(img, name[ids-1]+str(confidence), (x + 10, y - 10), cv.FONT_HERSHEY_COMPLEX, 0.75, (0, 255, 0), 1)else:ser.write('0'.encode())cv.putText(img, 'Unknown' , (x + 10, y - 10), cv.FONT_HERSHEY_COMPLEX, 0.75, (0, 255, 0),1)

这个过程中遇到了pycharm中opencv不提示代码的问题。

整了半天,才在这个大佬的文章中找到解决方案,http://t.csdn.cn/sQdN3

 (二)、自定义物体识别:

        在这个模块中我使用了自己训练的分类器

这是我的正样本 :

这是我的负样本 :

这是我最后的成果cascade.xml文件,也就是可以用的分类器:

        自己训练分类器时,我用opencv4.5.3版本,借鉴网上网上大佬发的文章自己实践,结果发现只有opencv_createsamples.exe可以勉强编译出来,但opencv_traincascade.exe确实编译不出来,为此我不得不又下载了opencv3.4.8的版本,使用其自带的那两个可执行程序进行训练。

        我使用了240张正样本,720张负样本,(正:负)==(1:3)(负样本一定要比正样本多,正负样本数量比例可以在1:3到1:5之间)。虽说样本数量不是很多,但效果还能接受。

        下面是我的正样本描述文件,说一下文件里面1 0 0 40 40 后缀的含义。

 我的正样本图片统一处理成了40*40,所以这里的1是指正样本图片中只有一个自定义的物体, 0 0 40 40的意思是覆盖整张图片

网上相关自己训练分类器的文章很多,具体的实现过程我也不在此过多地赘述了。

         分类器训练完了之后,就可以直接使用了,下面展示我的代码:

def object_Detector(image):gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)bottle_cascade = cv.CascadeClassifier('C:/opencv/Object/xml/cascade.xml')bottle = bottle_cascade.detectMultiScale(gray,1.1,5,cv.CASCADE_SCALE_IMAGE,(50,50),(300,300))num = len(bottle)for x,y,w,h in bottle :cv.circle(image,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1)cv.putText(image,str(num),(20,20),cv.FONT_HERSHEY_COMPLEX, 0.75, (0, 0, 255),1)

(三)、图片展示:

        由于项目要求,我的项目中opencv处理后的图片需要再我的单片机上显示,但这方面有点力不从心,所以我使用了socket实现opencv处理后的图片从客户端上传用服务端接受并展示。

这是客户端代码,从opencv中不断获取处理后的图片,进行编码、发送

#从客户端向服务端发送处理后的re_img图片
def SendVideo():global re_img, ret, state# IP地址和端口号IP = '127.0.0.1'PORT = 8002try:# 实例化:AF_INET:ip协议,SOCK_STREAM:tcp协议dataSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 开始连接dataSocket.connect((IP, PORT))# 错误处理except socket.error as msg:print(msg)sys.exit(1)# 压缩参数,对于jpeg来说,15代表图像质量,越高代表图像质量越好为 0-100,默认95encod_param = [int(cv.IMWRITE_JPEG_QUALITY), 15]while ret:# 停止0.05秒,防止发送过快服务的处理不过来time.sleep(0.05)# 将图片格式编码成流数据,方便网络传输# result:True/False# imgencode:numpy.ndarray类型的图像文件内容result, imgencode = cv.imencode('.jpg', re_img,encod_param)# 建立矩阵data = np.array(imgencode)# 将numpy矩阵转换成字符形式,以便在网络中传输stringData = data.tobytes()# ljust() 方法返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串dataSocket.send(str.encode(str(len(stringData)).ljust(16)))# 发送数据dataSocket.send(stringData)if state == True:breakdataSock.close()

这是服务端代码,不断从客户端里获取流数据,再进行一系列的转化、解码,最后展示到笔记本上 

def ReceiveVideo():global state# ip地址'0.0.0.0'绑定本机所有IP地址IP = '0.0.0.0'# 端口号PORT = 8002# 实例化listenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 进行IP和端口号的绑定# 元组方式写入# 可以啊address=('0.0.0.0',50000)listenSocket.bind((IP, PORT))# 最多接受1个客户端listenSocket.listen(1)# 消息边界def recallbyt(sock, cnt):byt = b''  # byt是一个byte类型,用于接受流数据。(传输的数据就是byte类型的)while cnt:newbyt = sock.recv(cnt)if not newbyt: return Nonebyt += newbytcnt -= len(newbyt)return bytdataSocket, addr = listenSocket.accept()print('连接到:' + str(addr))while True:# 获得图片文件长度,16代表获取长度length = recallbyt(dataSocket, 16)# 根据获取的文件长度,获取图片文件StringData = recallbyt(dataSocket, int(length))# 将流数据转换成numpy 1维数组数据data = np.frombuffer(StringData, np.uint8)# 将数组数据进行解码,形成图像deco_img = cv.imdecode(data, cv.IMREAD_COLOR)cv.imshow('SERVER', deco_img)# 按键检测if cv.waitKey(1) == 81:dataSocket.close()state = TruelistenSocket.close()cv.destroyAllWindows()break

(四)、python框架:

        整体采用了多线程的运行方式,并且在最开始通过一个判断来选择进行人脸识别模式还是自定义模块识别模式

thread_Rec = threading.Thread(target=ReceiveVideo)
thread_Sen = threading.Thread(target=SendVideo)
thread_take = threading.Thread(target=teak_img)'''*************************模式判断*************************'''
mode = input('请选择模式:')
if mode == '1':thread_face = threading.Thread(target=face_det)thread_face.start()
elif mode == '2':thread_obj = threading.Thread(target=object_det)thread_obj.start()
'''**************************************************'''thread_take.start()
thread_Rec.start()
thread_Sen.start()

因为想在一个python程序上就集成两个模式,对多线程的学习还没有很深入所以不得已做成这样的判断,来识别需要运行的模式

(五)、执行器--单片机:

        项目中,单片机通过串口与python程序相通,进行判断是否是数据库中的人,从而进行显示通过或失败。

void USART2_IRQHandler(void)
{u8 i,ret;if (USART_GetITStatus (USART2,USART_IT_RXNE )){ret = USART_ReceiveData(USART2);if (ret == '1' && (sate == 'N' || sate == 'E')){LCD_Clear (WHITE);POINT_COLOR=GREEN;for(i=0;i<8;i++){LCD_Draw_Circle( 120, 160, 102-i);}LCD_Fill( 110, 120 , 130,220 , GREEN);for (i=0;i<25;i++){LCD_DrawLine(80+i, 160,120, 110+i);}for (i=0;i<25;i++){LCD_DrawLine(160-i, 160,120, 110+i);}POINT_COLOR=BLACK;LCD_ShowString (65,20,200,16,16,"Knwon     Pass");LCD_ShowString(80,280,200,16,16,"2022/7/24");sate = 'Y';}else if (ret == '0' && (sate == 'Y' || sate == 'E')){LCD_Clear (WHITE);POINT_COLOR=RED;for(i=0;i<8;i++){LCD_Draw_Circle( 120, 160, 102-i);}for (i=0;i<25;i++){LCD_DrawLine(70+i, 210,146+i, 110);}for (i=0;i<25;i++){LCD_DrawLine(70+i, 110,146+i, 210);}LCD_ShowString (65,20,200,16,16,"Unknown   fail");LCD_ShowString(80,280,200,16,16,"2022/7/24");sate = 'N';}		}
}

四、效果展示:

 

LCD上其实还有一些字 ,只是亮度太高,看不见了 

五、总结 :

        这次的项目由于开始后的前两天一直在整face_recognition的代码到后来转到opencv自带的Haar特征分类器时有点“狼狈”,时间很紧张,来不及做其他的执行器模块。

        这个项目对我来说最难的是画面展示的部分,因为电脑和单片机之间的通信我不太熟悉,问了一下我的师兄其他方法,随后了解到flask可以将视频传输到网页上,但是整了两天也没整会如何将网页上的视频流信息捕捉回来,到了结束的前一天才了解到socket可以进行服务端和客户端的信息传输,就赶紧听课、学习、写代码。


http://chatgpt.dhexx.cn/article/ZU5hhRS7.shtml

相关文章

opencv物体识别-识别水果

前言 玩一玩用opencv做一些简单的物体识别 1.思路讲解 我们基于简单的opencv的阈值分割&#xff0c;通过这个阈值分割&#xff0c;我们能把我们需要识别的物体在二值图里面变成白色&#xff0c;其余的变成黑色。然后对我们分割出来的物体部分提取轮廓&#xff0c;算出覆盖轮…

物体识别

一、物体识别 图像识别&#xff1a;很重要&#xff0c;是很多算法的基础 图像识别定位&#xff1a;识别出来是猫&#xff0c;且定位出猫的位置 物体检测&#xff1a;每个图像中含有多物体&#xff0c;检测出有几个个体&#xff0c;并框出来位置 图像分割&#xff1a;不仅仅框…

【AI技术】物体识别概述1

【AI技术】物体识别概述1 1、背景2、物体识别3、应用 1、背景 主要针对客户以及初学者概述物体识别。 2、物体识别 物体识别又叫目标识别&#xff0c;物体分类&#xff0c;图像分类&#xff0c;习惯性称为图像分类&#xff0c;即对整张图片进行分类。 物体识别针对的是物体分…

目标检测和物体识别的方法有哪些?如何进行物体定位和分类?

目标检测和物体识别是计算机视觉领域中重要的任务&#xff0c;旨在从图像或视频中自动定位和识别出不同类别的物体。这些任务在许多应用领域中具有广泛的应用&#xff0c;如自动驾驶、视频监控、人机交互等。本文将介绍目标检测和物体识别的方法以及如何进行物体定位和分类。 一…

小程序 跳转 公众号 文章

1.通过组件 web-view https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html <web-view src"https://mp.weixin.qq.com/s/Cz4x4QpvF_Pozn7xjYOVyw"></web-view>2.如果是关联好小程序的公众号 1.如果是 左图文章 都是 https://m…

微信小程序跳转公众号h5页面

小程序提供了web- view组件进行用来内嵌网页 根据限制说明准备域名即可&#xff0c;开发阶断可以使用http的域名&#xff0c;在开发者工具中勾选不验证https证书即可&#xff0c;发布上线时必须使用https的域名。 同时需要小程序后台配置业务域名。

微信小程序跳转微信公众号

1 webview 嵌套 微信公众号的页面 然后 文章里 添加 公众号二维码 然后引导用户长按识别公众号 2 公众号有关注的页面 路径 需要自己找 我记得是替换什么officeid啥的 百度即可 3 利用<official-account bindload"lookSuccess" binderror"lookFai…

微信小程序跳转公众号

长按识别跳转 步骤&#xff1a; 新建一个页面使用web-view组件的src链接到公众号编辑好的一篇带有公众号的二维码的文章 微信规则只有小程序关联的公众号里的文章可以长按识别二维码 <template><view><!--微信规则只有小程序关联的公众号里的文章可以长按识别…

小程序直接跳转公众号的必要条件记录

1、小程序必须关联公众号主体&#xff0c;可以从图1查看是否已被关联&#xff0c;如果没有被关联&#xff0c;则可以去图2进行关联 图1&#xff1a; 图2&#xff1a;登录微信公众平台&#xff0c;进入图片广告-小程序管理&#xff0c;进行关联 2.小程序不能直接打开公众号首…

小程序跳转公众号文章

这是首页的代码 <image class"seedingBannar" data-id"{{item.id}}" bindtap"goTweet" src"{{resourceUrlitem.iconPath}}"></image>// 跳转到推文页面goTweet: function (e) {console.log(e.currentTarget.dataset.id)wx…

uni-app微信小程序跳转公众号;微信小程序打开公众号;微信小程序识别二维码添加好友;微信小程序通过公众号添加好友;小程序里识别企业微信二维码点击联系人名片无反应?

需求&#xff1a; 在微信小程序页面中&#xff0c;长按识别图片二维码&#xff0c;识别出联系人后&#xff0c;点击添加好友&#xff1b; 问题&#xff1a;微信官方社区说是小程序添加不了好友&#xff1b; 解决方案&#xff1a; 目前只能通过微信小程序跳转至公众号&#xf…

uniapp写小程序跳转公众号H5链接

需求&#xff1a; 需求是小程序的首页banner图来自pc端配置生产。 在小程序点击轮播的banner图后&#xff0c;跳到对应的linkurl&#xff0c;但是我们和客户约定好&#xff0c;只能跳转公众号。 一开始看了小程序的文档&#xff0c;需要配置什么业务域名&#xff0c;下载校验…

微信小程序如何跳转微信公众号

目录 一、微信公众号配置二、微信小程序配置三、添加代码 一、微信公众号配置 登录微信公众号&#xff0c;点击【小程序管理】&#xff1a; 点击【添加】&#xff1a; 点击【关联小程序】&#xff1a; 输入小程序进行关联&#xff1a; 二、微信小程序配置 登录微信小程序…

小程序跳转公众号关注页面的两种方法

一、web-view方法 这个种方法有一个必须要达到的条件就是&#xff1a;小程序的公众号必须是认证的企业号&#xff0c;而且要在小程序公众号的后台添加“veb-view业务域名”&#xff01;不然会出现如下情况 <!--pages/webview666/webview.wxml--> <view class"ty…

小程序 小程序跳转公众号页面

web-view 基础库 1.6.4 开始支持&#xff0c;低版本需做兼容处理。 承载网页的容器。会自动铺满整个小程序页面&#xff0c;个人类型的小程序暂不支持使用。 客户端 6.7.2 版本开始&#xff0c;navigationStyle: custom 对 web-view 组件无效 小程序插件中不能使用。 属性类…

微信小程序跳转公众号推文

注&#xff1a;笔者是自学小程序&#xff0c;自身开发经验不足&#xff0c;代码肯定存在不规范和不足&#xff0c;该博客参考一下就好 完整项目代码&#xff1a;https://github.com/zim-keavin/wxapp-cloud-demo 实现在小程序中&#xff0c;点击某个组件后跳转到公众号的推文…

微信小程序跳转公众号链接

小程序跳转微信公众号文章&#xff0c;是通过web-view实现的。 1.web-view会默认自动打开所跳转的页面&#xff0c;但我们一般项目需求是点击某一按钮或下一步进行跳转&#xff0c;所以在小程序中我们需要新建一个页面来承载web-view 在页面点击按钮后跳转至承载页面&#xff0…

React + Taro 小程序跳转公众号

Taro小程序跳转公众号的文章 步骤&#xff1a;登录公众号后台-小程序-小程序管理-添加-关联小程序 关联后就可以在微信的公众平台查看(设置-关联设置-关联公众号) 如图所示&#xff1a; 然后使用web-view 我这个是使用广告轮播实现的代码如下 注意&#xff1a;一个页面使用…

【实战】前端必会 —— 微信小程序 跳转 微信公众号

文章目录 一、跳转方案二、获取biz三、小程序跳转公众号 web-view | 微信开放文档 一、跳转方案 跳转方案的选择关键在于目的性&#xff1a; 引流关注&#xff1a;直接跳转公众号页面内容查看&#xff1a;使用 web-view 直接查看 二、获取biz biz 相当于微信公众号的 唯一身…

小程序和公众号相互跳转

小程序跳转公众号 小程序跳转公众号目前只找到 微信暴露的 引导关注组件 official-account, 官方文档如下&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/component/official-account.html 且这个组件展示是有限制的&#xff0c;只有在扫码进入小程序的情况下…