热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

计算机视觉:图像分类定位(单一目标检测)python实现

前言目标检测:我们不仅要用算法判断图片中是不是猫还是狗,还要在图片中标记出它的位置,用边框或红色方框把猫狗圈起来,这就是目标检测问题。其中“定位”的意思是判断猫狗在图片中的具体位置

前言

目标检测:我们不仅要用算法判断图片中是不是猫还是狗, 还要在图片中标记出它的位置, 用边框或红色方框把猫狗圈起来, 这就是目标检测问题。其中“定位”的意思是判断猫狗在图片中的具体位置。

目标检测有两类任务:单一目标 ,多目标。

能力差,电气专业,又未怎么深入研究cv.
所以本文先探讨单一目标。
《计算机视觉:图像分类定位(单一目标检测)python实现》

HOG+SVM实现行人检测

先讲解 opencv自带的行人检测例子
HOG原理见
计算机视觉:图像特征与描述大全 ,有代码(一篇博文带你简单了解完图像特征提取技术)

不多说,上代码

import cv2 as cv
# 读取图像
src = cv.imread("duoren.jpg")
cv.imshow("input", src)
# HOG + SVM
hog = cv.HOGDescriptor()
hog.setSVMDetector(cv.HOGDescriptor_getDefaultPeopleDetector())
# Detect people in the image
(rects, weights) = hog.detectMultiScale(src,winStride=(4, 4), padding=(8, 8),scale=1.25,useMeanshiftGrouping=False)
# 矩形框
for (x, y, w, h) in rects:
cv.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示[添加链接描述](https://blog.csdn.net/kobeyu652453/article/details/107382227)
cv.imshow("result", src)
cv.waitKey(0)
cv.destroyAllWindows()

《计算机视觉:图像分类定位(单一目标检测)python实现》

图像定位实现

python +keras实现图像分类(入门级例子讲解)
opencv进阶学习笔记12:轮廓发现和对象测量

目标检测算法很复杂。
我尝试用 图像分类+对象测量 来实现单目标的图像检测。

图像分类 对象测量 不多说了,参考上面给的链接。

1读取图片并去噪

import cv2 as cv
image= cv.imread("catdog/dog/dog.77.jpg")
image=cv.resize(image,None,fx=0.5,fy=0.5)
blurred = cv.GaussianBlur(image, (5, 5), 0) # 去噪

2二值化图像

gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)

3绘制轮廓边缘

contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

cv2.findContours()函数第一个参数是要检索的图片,必须是为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图,
参数讲解
contours,hierarchy=cv2.findContours(image,mode,method)
contours:轮廓
hierarchy:图像的拓扑信息(轮廓层次)(存储上一个轮廓,父轮廓…)
image:二值图像
mode:轮廓检索方式
method:轮廓的近似方法

《计算机视觉:图像分类定位(单一目标检测)python实现》
《计算机视觉:图像分类定位(单一目标检测)python实现》

4求得包含点集最小面积的矩形,这个矩形是可以有偏转角度的,可以与图像的边界不平行。

c = sorted(contours, key=cv.contourArea, reverse=True)[0]
rect = cv.minAreaRect(c)
box = np.int0( cv.boxPoints(rect))
# draw a bounding box arounded the detected barcode and display the image
cv.drawContours(image, [box], -1, (0, 255, 0), 3)

讲解

double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ );
contour:轮廓(顶点的序列或数组)。
slice:感兴趣区轮廓部分的起点和终点,默认计算整个轮廓的面积。

c = sorted(contours, key=cv.contourArea, reverse=True)[0]
取出最大的轮廓面积,有些轮廓为噪声。
最大轮廓一般情况下能取到我们想要的目标物。

minAreaRect函数返回矩形的中心点坐标,长宽,旋转角度[-90,0),当矩形水平或竖直时均返回-90

使用cv2.boxPoints()可获取该矩形的四个顶点坐标。 浮点型数据

np.int0 取整

r=cv2.drawContours(image, contours, contourIdx, color[, thickness])
r:目标图像
image:原始图像
contours: 所有的输入轮廓边缘数组
contourIdx :需要绘制的边缘索引,如果全部绘制为-1。如果有多个目标,可以绘制第一个目标0,第二个目标1,第三个目标2.。。
color:绘制的颜色,为BGR格式的SCalar
thickness:可选,绘制的密度,即轮廓的画笔粗细

5找出四个顶点的x,y坐标的最大最小值。矩形框的高=maxY-minY,宽=maxX-minX。

由于前面的提到的 包含点集最小面积的矩形 有的矩形不与图像平行,是斜着的,如下图。我们调整矩形框。
《计算机视觉:图像分类定位(单一目标检测)python实现》

Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
cropImg = image[y1:y1 + hight, x1:x1 + width]
cv.rectangle(image, (x1, y1), (x1 + width, y1 +hight ), (0, 0, 255), 2) # 在原图上,给轮廓绘制矩形
cv.imshow('result',image)

《计算机视觉:图像分类定位(单一目标检测)python实现》

所有代码

import cv2 as cv
import numpy as np
src= cv.imread("dog.16.jpg")
src=cv.resize(src,None,fx=0.5,fy=0.5)
image=src.copy()
#去噪
blurred = cv.GaussianBlur(image, (5, 5), 0) # 去噪
#灰度转换
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
#二值化
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
#轮廓发现
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
#取出最大轮廓
c = sorted(contours, key=cv.contourArea, reverse=True)[0]
#找到最大轮廓的最小外接矩形
rect = cv.minAreaRect(c)
#取出最小外接矩形的四个顶点
box = np.int0( cv.boxPoints(rect))
#绘制矩形框
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
cropImg = image[y1:y1 + hight, x1:x1 + width]
cv.rectangle(image, (x1, y1), (x1 + width, y1 + hight), (0, 0, 255), 2) # 在原图上,给轮廓绘制矩形
#显示
cv.imshow("input image", src)
cv.imshow('result', image)
cv.waitKey(0)
cv.destroyAllWindows()

《计算机视觉:图像分类定位(单一目标检测)python实现》

图像分类定位实现

我应用图像分类 加前面提到的定位 结合起来做 单目标的图像监测。

图像分类前面给出了链接,这里不再给啦,博文太多链接了,会被显示待审核。

PYQT 封装吧。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: yudengwu
# @Date : 2020/8/1
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import cv2
import keras
from keras .models import load_model
import numpy as np
import re
class picture(QWidget):
def __init__(self):
super(picture, self).__init__()
self.resize(600, 400)
self.setWindowTitle("猫狗分类")
self.btn = QPushButton()
self.btn.setText("打开图片")
self.btn.clicked.connect(self.openimage)
self.label = QLabel()
self.label.setText('图片路径')
self.labelimage = QLabel()
self.labelimage.setText("显示图片")
#self.labelimage.setFixedSize(500, 400)#设置尺寸
self.labelimage.setStyleSheet("QLabel{background:white;}"
"QLabel{color:rgb(300,300,300,120);font-size:10px;font-weight:bold;font-family:宋体;}"
)
#预测按钮
self.btnclass=QPushButton()
self.btnclass.setText('点击预测分类')
self.btnclass.clicked.connect(self.fenlei)
self.labelclass=QLabel()
self.labelclass.setText('预测类别')
self.labelclass.setStyleSheet("font:16pt '楷体';border-width:2px;border-style: inset;border-color:gray")
layout1=QVBoxLayout()
layout1.addWidget(self.btn)
layout1.addWidget(self.label)
layout1.addWidget(self.labelimage)
layout2 = QVBoxLayout()
layout2.addWidget(self.btnclass)
layout2.addWidget(self.labelclass)
layout=QVBoxLayout()
layout.addLayout(layout1)
layout.addLayout(layout2)
self.setLayout(layout)
def openimage(self):
imgName, imgType = QFileDialog.getOpenFileName(self, "打开图片", "", "*.jpg;;*.png;;All Files(*)")
#jpg = QtGui.QPixmap(imgName).scaled(self.labelimage.width(), self.label.height())#适应labelimage尺寸,前提是label设置了尺寸
jpg = QtGui.QPixmap(imgName)
self.labelimage.setPixmap(jpg)
self.label.setText(str(imgName))
def fenlei(self):
biaoqian = { '1': '猫', '0': '狗'}
path=self.label.text()
newName = re.sub('(D:/机器学习/学习草稿/)','', path)
#print(newName)
img = cv2.imread(str(newName))
img = cv2.resize(img, (100, 100)) # 使尺寸大小一样
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = np.array(img) / 255
img = img.astype(np.float64)
img = img.reshape(-1, 100, 100, 1)
model = load_model('猫狗分类.h5')
predict_y = model.predict(img)
pred_y = int(np.round(predict_y))
#print(pred_y)
self.labelclass.setText(biaoqian[str(pred_y)])
########图像定位
src = cv2.imread(str(newName))
src = cv2.resize(src, None, fx=0.5, fy=0.5)
image = src.copy()
# 去噪
blurred = cv2.GaussianBlur(image, (5, 5), 0) # 去噪
# 灰度转换
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
# 二值化
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 轮廓发现
contours, hireachy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 取出最大轮廓
c = sorted(contours, key=cv2.contourArea, reverse=True)[0]
# 找到最大轮廓的最小外接矩形
rect = cv2.minAreaRect(c)
# 取出最小外接矩形的四个顶点
box = np.int0(cv2.boxPoints(rect))
# 绘制矩形框
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
cropImg = image[y1:y1 + hight, x1:x1 + width]
cv2.rectangle(image, (x1, y1), (x1 + width, y1 + hight), (0, 0, 255), 2) # 在原图上,给轮廓绘制矩形
#显示在lableimage上
res = image
res = cv2.resize(res, (400, 300), interpolation=cv2.INTER_CUBIC) # 用cv2.resize设置图片大小
img2 = cv2.cvtColor(res, cv2.COLOR_BGR2RGB) # opencv读取的bgr格式图片转换成rgb格式
_image = QtGui.QImage(img2[:], img2.shape[1], img2.shape[0], img2.shape[1] * 3,
QtGui.QImage.Format_RGB888) # pyqt5转换成自己能放的图片格式
jpg_out = QtGui.QPixmap(_image) # 转换成QPixmap
self.labelimage.setPixmap(jpg_out) # 设置图片显示
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
my = picture()
my.show()
sys.exit(app.exec_())

说明:

model = load_model(‘猫狗分类.h5’)
导入训练好的分类模型

在PYQT中显示opencv图 核心代码

def setImage(self):
img = cv2.imread('test.jpg') #opencv读取图片
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #opencv读取的bgr格式图片转换成rgb格式
_image = QtGui.QImage(img2[:], img2.shape[1], img2.shape[0], img2.shape[1] * 3, QtGui.QImage.Format_RGB888) #pyqt5转换成自己能放的图片格式
jpg_out = QtGui.QPixmap(_image).scaled(self.imgLabel.width(), self.imgLabel.height()) #设置图片大小
self.imgLabel.setPixmap(jpg_out) #设置图片显示

结果演示

《计算机视觉:图像分类定位(单一目标检测)python实现》
《计算机视觉:图像分类定位(单一目标检测)python实现》

本文给出的方法不是纯粹的目标检测算法。定位有的图有所缺陷。

只是图像分类+对象测量 来实现单一目标检测功能

等我有时间研究下目标检测算法后,再来写博文。

电气专业的计算机萌新:余登武,写博文不容易,如果你觉得本文对你有用,请点个赞支持下,谢谢。

《计算机视觉:图像分类定位(单一目标检测)python实现》


推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
author-avatar
布瓜Pourqu2502854853
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有