0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Python-OpenCV实现餐盘水果识别与计价的应用

新机器视觉 来源:OpenCV与AI深度学习 作者: Color Space 2021-07-06 11:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

导读本文主要介绍使用Python-OpenCV实现餐盘水果识别与计价的应用。

测试图像与说明

使用图像,拍摄环境有待改善(存在光照不均和拍摄角度的影响):

餐盘/菜品识别一般方法:

(1)识别餐盘---传统方法和机器学习/深度学习方法;

(2)识别菜品---机器学习/深度学习方法;

本文使用传统方法识别餐盘。

效果演示:

算法思路与实现步骤

思路:传统方法识别餐盘---依据颜色和形状来区分。

具体步骤:

(1)餐盘颜色共三种:白色、绿色、橙色,形状共两种:圆形和方形。区别颜色使用HSV阈值范围筛选即可,圆形与方形通过轮廓面积与轮廓最小外接圆面积的比值来筛选,圆形rate》=0.9,方形《0.9;

(2)水果共三种:苹果、香蕉、橙子,通过颜色可以区分苹果和橙子,通过轮廓最小外接矩形的宽高比可以区分香蕉和橙子;

(3)计价:盘子和水果的数量乘以对应的单价即可;

(4)设计UI,计价时显示收款码。

Python-OpenCV实现算法核心代码与效果如下:

def Recognize_Dish(self,img): #-------------------香蕉检测-----------------# banana_num = 0 hsv_img=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) lower_yellow = np.array([15,30,145])#颜色范围低阈值 upper_yellow = np.array([35,255,255])#颜色范围高阈值 mask = cv2.inRange(hsv_img,lower_yellow,upper_yellow)#根据颜色范围删选 mask = cv2.medianBlur(mask, 5)#中值滤波 #cv2.imshow(‘mask_banana’, mask) contours,hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt in contours: rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) width = max(rect[1][0],rect[1][1]) height = min(rect[1][0],rect[1][1]) center = (int(rect[0][0]),int(rect[0][1])) if width 》 180 and height 》 80 and height 《 130: #print(width,height) img = cv2.drawContours(img,[box],0,(0,0,255),2) cv2.putText(img,‘banana’,center,font,1,(255,0,255), 2) banana_num += 1 item_0 = QTableWidgetItem(“%d”%banana_num) self.tableWidget.setItem(8, 0, item_0)

#-------------------苹果检测-----------------# apple_num = 0 lower_apple = np.array([0,50,50])#颜色范围低阈值 upper_apple = np.array([30,255,255])#颜色范围高阈值 mask_apple = cv2.inRange(hsv_img,lower_apple,upper_apple)#根据颜色范围删选 mask_apple = cv2.medianBlur(mask_apple, 9)#中值滤波 #cv2.imshow(‘mask_apple’, mask_apple) #cv2.imwrite(‘mask_apple.jpg’, mask_apple) contours2,hierarchy2 = cv2.findContours(mask_apple, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt2 in contours2: center,radius = cv2.minEnclosingCircle(cnt2) area = cv2.contourArea(cnt2) #print(radius) rate = area / (math.pi * radius *radius) if radius 》 50 and radius 《 75 and rate 《 0.91: #print(radius) cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(0,255,0),2) cv2.putText(img,‘apple’,(int(center[0]),int(center[1])),font,1,(255,0,0), 2) apple_num += 1 item_1 = QTableWidgetItem(“%d”%apple_num) self.tableWidget.setItem(6, 0, item_1)

#-------------------橘子检测-----------------# orange_num = 0 lower_orange = np.array([0,90,60])#颜色范围低阈值 upper_orange = np.array([60,255,255])#颜色范围高阈值 mask_orange = cv2.inRange(hsv_img,lower_orange,upper_orange)#根据颜色范围删选 mask_orange = cv2.medianBlur(mask_orange, 5)#中值滤波 #cv2.imshow(‘mask_orange’, mask_orange) #cv2.imwrite(‘mask_orange.jpg’, mask_orange) contours3,hierarchy3 = cv2.findContours(mask_orange, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt3 in contours3: center,radius = cv2.minEnclosingCircle(cnt3) area = cv2.contourArea(cnt3) #print(radius) rate = area / (math.pi * radius *radius) if radius 》 50 and radius 《 75 and rate 》 0.85: #print(radius) cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(255,0,255),2) cv2.putText(img,‘orange’,(int(center[0]),int(center[1])),font,1,(255,255,0), 2) orange_num += 1 item_2 = QTableWidgetItem(“%d”%orange_num) self.tableWidget.setItem(7, 0, item_2)

#-------------------白色餐盘检测-----------------# white_circle_num = 0 white_rect_num = 0 lower_white = np.array([0,0,150])#颜色范围低阈值 upper_white= np.array([100,55,255])#颜色范围高阈值 mask_white = cv2.inRange(hsv_img,lower_white,upper_white)#根据颜色范围删选 mask_white = cv2.medianBlur(mask_white, 5)#中值滤波 #cv2.imshow(‘mask_white’, mask_white) #cv2.imwrite(‘mask_white.jpg’, mask_white) contours4,hierarchy4 = cv2.findContours(mask_white, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt4 in contours4: area = cv2.contourArea(cnt4) center,radius = cv2.minEnclosingCircle(cnt4) #print(radius) rate = area / (math.pi * radius *radius) if radius 》 100 and radius 《 160: #print(radius) if rate 》= 0.9: cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(255,255,0),2) cv2.putText(img,‘white_circle’,(int(center[0]),int(center[1])),font,1,(0,255,0), 2) white_circle_num += 1 elif rate 》0.6 and rate 《 0.9: rect = cv2.minAreaRect(cnt4) box = cv2.boxPoints(rect) box = np.int0(box) #cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(255,0,255),5) img = cv2.drawContours(img,[box],0,(255,255,0),2) cv2.putText(img,‘white_rect’,(int(center[0]),int(center[1])),font,1,(0,255,0), 2) white_rect_num += 1 item_3 = QTableWidgetItem(“%d”%white_circle_num) self.tableWidget.setItem(0, 0, item_3) item_4 = QTableWidgetItem(“%d”%white_rect_num) self.tableWidget.setItem(1, 0, item_4)

#-------------------绿色餐盘检测-----------------# green_circle_num = 0 green_rect_num = 0 lower_green = np.array([30,65,65])#颜色范围低阈值 upper_green= np.array([80,255,255])#颜色范围高阈值 mask_green = cv2.inRange(hsv_img,lower_green,upper_green)#根据颜色范围删选 mask_green = cv2.medianBlur(mask_green, 5)#中值滤波 #cv2.imshow(‘mask_green’, mask_green) #cv2.imwrite(‘mask_green.jpg’, mask_green) contours5,hierarchy5 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt5 in contours5: area = cv2.contourArea(cnt5) center,radius = cv2.minEnclosingCircle(cnt5) #print(radius) rate = area / (math.pi * radius *radius) if radius 》 100 and radius 《 160: #print(radius) if rate 》= 0.9: cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(0,255,0),2) cv2.putText(img,‘green_circle’,(int(center[0]),int(center[1])),font,1,(0,255,255), 2) green_circle_num += 1 elif rate 》0.6 and rate 《 0.9: rect = cv2.minAreaRect(cnt5) box = cv2.boxPoints(rect) box = np.int0(box) #cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(255,0,255),5) img = cv2.drawContours(img,[box],0,(0,255,0),2) cv2.putText(img,‘green_rect’,(int(center[0]),int(center[1])),font,1,(0,255,255), 2) green_rect_num += 1 item_5 = QTableWidgetItem(“%d”%green_circle_num) self.tableWidget.setItem(4, 0, item_5) item_6 = QTableWidgetItem(“%d”%green_rect_num) self.tableWidget.setItem(5, 0, item_6)

#-------------------橙色餐盘检测-----------------# orange_circle_num = 0 orange_rect_num = 0 lower_orange_dish = np.array([0,100,100])#颜色范围低阈值 upper_orange_dish= np.array([15,255,255])#颜色范围高阈值 mask_orange_dish = cv2.inRange(hsv_img,lower_orange_dish,upper_orange_dish)#根据颜色范围删选 mask_orange_dish = cv2.medianBlur(mask_orange_dish, 5)#中值滤波 #cv2.imshow(‘mask_green’, mask_green) #cv2.imwrite(‘mask_orange_dish.jpg’, mask_orange_dish) contours6,hierarchy6 = cv2.findContours(mask_orange_dish, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt6 in contours6: area = cv2.contourArea(cnt6) center,radius = cv2.minEnclosingCircle(cnt6) #print(‘----------------’) #print(radius) rate = area / (math.pi * radius *radius) if radius 》 100 and radius 《 160: #print(rate) if rate 》= 0.8: cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(0,255,0),2) cv2.putText(img,‘orange_circle’,(int(center[0]),int(center[1])),font,1,(255,0,255), 2) orange_circle_num += 1 elif rate 》0.3 and rate 《 0.8: rect = cv2.minAreaRect(cnt6) box = cv2.boxPoints(rect) box = np.int0(box) #cv2.circle(img,(int(center[0]),int(center[1])),int(radius),(255,0,255),5) img = cv2.drawContours(img,[box],0,(0,255,0),2) cv2.putText(img,‘orange_rect’,(int(center[0]),int(center[1])),font,1,(255,0,255), 2) orange_rect_num += 1 item_7 = QTableWidgetItem(“%d”%orange_circle_num) self.tableWidget.setItem(2, 0, item_7) item_8 = QTableWidgetItem(“%d”%orange_rect_num) self.tableWidget.setItem(3, 0, item_8)

for i in range(0,9): self.tableWidget.item(i,0).setTextAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter) self.tableWidget.item(i,1).setTextAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter) #----------------计算价格--------------# self.price = self.price_white_circle * white_circle_num + self.price_white_rect * white_rect_num + self.price_orange_circle * orange_circle_num + self.price_orange_rect * orange_rect_num + self.price_green_circle * green_circle_num + self.price_green_rect * green_rect_num + self.price_apple * apple_num + self.price_orange * orange_num + self.price_banana * banana_num print(self.price) return img

结尾语

(1) 算法只针对水果和餐盘数量和形态较少的情形,方法供参考;

(2) 实际应用将更复杂,要求更高,一般开源的目标检测网络也很难满足要求;

(3) 常见菜品识别的实际应用要求:一个菜只用一张图片训练或做模板,训练和识别时间尽量短,能够及时更新使用。所以真正类似的产品并不好做,如果你有好的方法欢迎留言。

—版权声明—

来源: OpenCV与AI深度学习

仅用于学术分享,版权属于原作者。

若有侵权,请联系删除或修改!

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73137
  • 机器学习
    +关注

    关注

    66

    文章

    8541

    浏览量

    136230
  • OpenCV
    +关注

    关注

    33

    文章

    651

    浏览量

    44409
  • python
    +关注

    关注

    57

    文章

    4857

    浏览量

    89571
  • 深度学习
    +关注

    关注

    73

    文章

    5590

    浏览量

    123900

原文标题:应用实例 | 手把手教你用OpenCV实现餐盘水果识别计价程序(附代码)

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【EASY EAI Orin Nano开发板试用体验】PP-OCRV5文字识别实例搭建与移植

    【EASY EAI Orin Nano开发板试用体验】PP-OCRV5文字识别实例搭建与移植 PP-OCRV5是PP-OCR新一代文字识别解决方案, 该方案聚焦于多场景、多文字类型的文字识别。在
    发表于 08-18 16:57

    零成本钢铁侠手套!树莓派+OpenCV 秒变手势遥控器!

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追
    的头像 发表于 08-16 16:16 882次阅读
    零成本钢铁侠手套!树莓派+<b class='flag-5'>OpenCV</b> 秒变手势遥控器!

    如何使用树莓派与OpenCV实现面部和运动追踪的云台系统?

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追
    的头像 发表于 08-14 17:45 957次阅读
    如何使用树莓派与<b class='flag-5'>OpenCV</b><b class='flag-5'>实现</b>面部和运动追踪的云台系统?

    如何使用树莓派+OpenCV实现姿态估计和面部特征点追踪?

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追
    的头像 发表于 08-13 17:44 970次阅读
    如何使用树莓派+<b class='flag-5'>OpenCV</b><b class='flag-5'>实现</b>姿态估计和面部特征点追踪?

    【GM-3568JHF开发板免费体验】OpenCV开发环境安装和计数程序开发

    、 Android 等系统上运行,并通过Python接口简化操作。 sudo apt install libopencv-dev python3-opencv 四、OpenCV图像识别
    发表于 08-09 13:30

    如何板端编译OpenCV并搭建应用--基于瑞芯微米尔RK3576开发板

    INSTALL_PYTHON_EXAMPLES=OFF -D OPENCV_GENERATE_PKGCONFIG=ON -D OPENCV_EXTRA_MODULES_PATH=/home/myir/Downloads
    发表于 08-08 17:14

    用树莓派 + OpenCV 打造人脸识别技术!

    在本指南中,我们将教您如何使用OpenCV和面部识别库(两个出色的开源项目)设置树莓派来检测和识别面部。在这个设置中,所有的数据和处理都将在Pi上本地执行,这意味着您的所有面部和数据都不会离开Pi
    的头像 发表于 07-29 17:27 1008次阅读
    用树莓派 + <b class='flag-5'>OpenCV</b> 打造人脸<b class='flag-5'>识别</b>技术!

    【Milk-V Duo S 开发板免费体验】SDK编译、人脸检测、OpenCV测试

    -mobile-test ./opencv-mobile-test 生成 200x200 尺寸的 out.jpg 图像,即实现图片压缩。 该测试工程可结合物体识别模型,实现输入图像
    发表于 07-11 13:48

    基于LockAI视觉识别模块:手写数字识别

    1.1 手写数字识别简介 手写数字识别是一种利用计算机视觉和机器学习技术自动识别手写数字的过程。它通过图像预处理、特征提取和模型训练来实现高效准确的数字
    发表于 06-30 16:45

    AI视觉识别收银称:水果生鲜店的“智能店员”

    水果生鲜店中,采用AI视觉识别收银称不仅提升了顾客的购物体验,也为商家带来了诸多便利和效益。本文将详细介绍这一技术的好处。一、提升收银效率传统的收银方式需要人工逐一识别商品并进行称重、计价
    的头像 发表于 06-07 10:19 497次阅读
    AI视觉<b class='flag-5'>识别</b>收银称:<b class='flag-5'>水果</b>生鲜店的“智能店员”

    OpenVINO™工具套件使用CRNN_CS模型运行OpenCV* text_detection.cpp报错怎么解决?

    将 crnn_cs.onnx 文本识别模型转换为中间表示 (IR): python mo.py --input_model crnn_cs.onnx 使用生成的 IR 文件运行 OpenCV
    发表于 03-05 09:19

    高端水果价格跳水!高光谱技术如何影响水果品质筛选?

    高光谱技术在水果果实的品质检测中展现了强大的优势,能够精准识别损伤部位,并有效评估损伤程度,从而提升筛选效率和果品质量。无论是车厘子、青香蕉还是黄桃,高光谱技术都能提供一致且可靠的检测结果,确保水果的质量符合市场要求。
    的头像 发表于 02-19 16:16 568次阅读
    高端<b class='flag-5'>水果</b>价格跳水!高光谱技术如何影响<b class='flag-5'>水果</b>品质筛选?

    【实战】人工智能0基础入门:基于Python+OpenCV的车牌识别项目(课程+平台实践)

    的车牌识别系统项目。02项目功能本项目致力于利用摄像头捕获的图像数据,通过先进的图像处理和模式识别技术,实现对车牌的自动检测与识别。项目的核心在于精准的图像预处理
    的头像 发表于 12-16 10:43 1175次阅读
    【实战】人工智能0基础入门:基于<b class='flag-5'>Python+OpenCV</b>的车牌<b class='flag-5'>识别</b>项目(课程+平台实践)

    如何用OpenCV进行手势识别--基于米尔全志T527开发板

    本文将介绍基于米尔电子MYD-LT527开发板(米尔基于全志T527开发板)的OpenCV手势识别方案测试。摘自优秀创作者-小火苗米尔基于全志T527开发板一、软件环境安装1.安装OpenCVsudoapt-getinstalllibopencv-devpython3-
    的头像 发表于 12-13 08:04 1762次阅读
    如何用<b class='flag-5'>OpenCV</b>进行手势<b class='flag-5'>识别</b>--基于米尔全志T527开发板

    【AI实战项目】基于OpenCV的“颜色识别项目”完整操作过程

    适用于哪些场景,然后通过Python编写代码来实现这些算法,并应用于实际项目中,实现图像的检测、识别、分类、定位、测量等目标。华清远见【python
    的头像 发表于 12-09 16:42 1893次阅读
    【AI实战项目】基于<b class='flag-5'>OpenCV</b>的“颜色<b class='flag-5'>识别</b>项目”完整操作过程