是在检测图片的基础上进行加工的 详情可看opencv图片倾斜度检(一)对图片进行检测
打开摄像头进行实时检测矩形轮廓,实时画出坐标轴坐标点和倾斜度,并且具有保存图片和利用plot单纯画出矩形的功能

直接上全部代码 注释已经比较详细了
如下:

from matplotlib.cm import register_cmap
import matplotlib.pyplot as plt
import cv2
import numpy as np
import imutils
import time
from scipy.spatial import distance as dist#调用摄像头 函数
def read_usb_capture():# 选择摄像头的编号cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)# 0是笔记本自带摄像头# 添加这句是可以用鼠标拖动弹出的窗体cv2.namedWindow('video', cv2.WINDOW_NORMAL)while (cap.isOpened()):#循环ret, frame = cap.read()#read放回2个值,第一个是True和False 是否打开 第二个是传入图像lunkuo(frame)#进行轮廓检测cv2.imshow('video', frame)#显示出来k = cv2.waitKey(1) & 0xFF#监听键盘if k == ord('s'):# 保存键cv2.imwrite("1.jpg", frame)img = cv2.imread('1.jpg')cv2.imshow('img',img)# 按下'q'就退出if k == ord('q'):#退出键break# 释放画面cap.release()cv2.destroyAllWindows()
def midpoint(ptA, ptB):#计算坐标中点函数return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
def show(img):  # 显示图片函数cv2.imshow('img', img)cv2.waitKey(0)cv2.destroyAllWindows()def lunkuo(img):#检测轮廓start = time.time()#计算检测时间img1_ = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度img_ = cv2.GaussianBlur(img1_, (5, 5), 0)  # 高斯滤波去噪点img__ = cv2.Canny(img_, 75, 200)  # Canny边缘检测img__ = cv2.dilate(img__, None, iterations=1)#扩张img__ = cv2.erode(img__, None, iterations=1)#腐蚀# 轮廓检测cnts = cv2.findContours(img__.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)  # 检测出所有轮廓cnts = cnts[1] if imutils.is_cv3() else cnts[0]  # opencv4写法cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:]  # 排序得到前x个轮廓 可以根据图片自己设定#定义全局变量global screenCnt,box,ranglebox = 0rangle = 0# 我的摄像头分辨率为640*480 在摄像头中框出最合适检测的地方cv2.line(img, (595, 45), (595, 435),(255, 0, 255), 1)cv2.line(img, (45, 435), (595, 435),(255, 0, 255), 1)cv2.line(img, (45, 45), (45, 435),(255, 0, 255), 1)cv2.line(img, (45, 45), (595, 45),(255, 0, 255), 1)cv2.line(img, (45, 45), (595, 45),(255, 0, 255), 1)cv2.circle(img, (45, 45), 2, (255, 0, 0), -1)#中心点cv2.putText(img, "(0,0)",(45, 435), cv2.FONT_HERSHEY_SIMPLEX,0.5, (0, 244, 245), 2)#摄像头的坐标轴原点是在左上角 自己设定坐标轴原点并显示#遍历轮廓for c in cnts:# 计算轮廓近似peri = cv2.arcLength(c, True)# C表示输入的点集# epsilon表示从原始轮廓到近似轮廓的最大距离,它是一个准确度参数# True表示封闭的approx = cv2.approxPolyDP(c, 0.02 * peri, True)# 4个点的时候就拿出来 因为物品是矩阵形状if len(approx) == 4:screenCnt = approx  # 保存下来rangle = cv2.minAreaRect(screenCnt)[2]  # minAreaRect()函数返回角度 是最低的边到x水平坐标轴的角度box = cv2.cv.BoxPoints(cv2.minAreaRect(screenCnt)) if imutils.is_cv2() else cv2.boxPoints(cv2.minAreaRect(screenCnt))#得到四个最小矩阵的坐标点cv2.drawContours(img, [box.astype("int")], -1, (0, 255, 0), 2)#在图中画出来box = np.array(box, dtype="int")#转换类型(tl, tr, br, bl) = box#得到左上 右上 左下 右下的坐标点#计算中点(tltrX, tltrY) = midpoint(tl, tr)(blbrX, blbrY) = midpoint(bl, br)(tlblX, tlblY) = midpoint(tl, bl)(trbrX, trbrY) = midpoint(tr, br)#欧几里得度量dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))#固定摄像头及分辨率时 要想测出所测物品的长度 需要参照物 先使用已知宽度的矩形进行测量 得到 像素宽/实际宽 = 每宽多少像素 并保存下来# print('DB:',dB)# i = 1# if i == 1:#     pixelsPerMetric = dB / 3.4# print(pixelsPerMetric)# i += 1pixelsPerMetric = 35.15#得到的比率#分辨率除以比率可以得到摄像头测的实际范围长度# print('H:',640/pixelsPerMetric)# print('w:',480/pixelsPerMetric)if pixelsPerMetric != 0:#防止出现检测中没有实物得不到比例而发生除以0的错误#实际宽度dimA = dA / pixelsPerMetricdimB = dB / pixelsPerMetric#显示宽度cv2.putText(img, "{:.1f}cm".format(dimB),(int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)cv2.putText(img, "{:.1f}cm".format(dimA),(int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)#显示角度 此角度是经过变换后的 是我定义的坐标轴的矩形的最低点与x轴的夹角cv2.putText(img, "r:{:.1f}".format(90 - rangle),(int(tltrX + 20), int(tltrY + 20)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)#画出点的坐标的直线并显示坐标点数据 容易观察夹角的位置 并且可以利用坐标计算夹角cv2.line(img, (int(bl[0]), int(bl[1])), (int(bl[0]), 435),(0, 244, 245), 1)cv2.putText(img, "({},{})".format(bl[0], 640 - bl[1]),(int(bl[0] - 20), 415), cv2.FONT_HERSHEY_SIMPLEX,0.4, (225, 190, 0), 1)cv2.line(img, (int(br[0]), int(br[1])), (int(br[0]), 435),(0, 244, 245), 1)cv2.putText(img, "({},{})".format(br[0], 640 - br[1]),(int(br[0]), 435), cv2.FONT_HERSHEY_SIMPLEX,0.4, (225, 190, 0), 1)cv2.line(img, (int(bl[0]), int(bl[1])), (int(595), int(bl[1])),(0, 244, 245), 1)end = time.time()#时间print("轮廓检测所用时间:{:.3f}ms".format((end - start) * 1000))#得到坐标点在plot上进行绘画以及保存# x = [-tr[0], -tl[0], -br[0], -bl[0], -tr[0]]# y = [tr[1], tl[1], br[1], bl[1], tr[1]]# plt.plot(x, y)# plt.axhline(y=min(y), c="r", ls="--", lw=2)# plt.title("rangel = {}".format(rangle))# for a, b in zip(x, y):#     plt.text(a, b, (a, b), ha='center', va='bottom', fontsize=10)#plt.savefig('D:\zuobiao.png')return imgread_usb_capture()#开始

代码结果如下:

新增一个按下d键打开轮廓的坐标图功能
将画图部分整合成函数,使用全局变量作为触发标志
代码如下:

from matplotlib.cm import register_cmap
import matplotlib.pyplot as plt
import cv2
import numpy as np
import imutils
import time
from scipy.spatial import distance as dist
from PIL import  Imageglobal d#全局变量拿来判断是否按下d
d = 0
#调用摄像头 函数
def read_usb_capture():# 选择摄像头的编号cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)# 0是笔记本自带摄像头# 添加这句是可以用鼠标拖动弹出的窗体cv2.namedWindow('video', cv2.WINDOW_AUTOSIZE)cv2.resizeWindow("video", 640, 480)  # 设置长和宽while (cap.isOpened()):#循环ret, frame = cap.read()#read放回2个值,第一个是True和False 是否打开 第二个是传入图像lunkuo(frame)#进行轮廓检测cv2.imshow('video', frame)#显示出来k = cv2.waitKey(1) & 0xFF  # 监听键盘if k == ord('s'):# 保存键cv2.imwrite("1.jpg", frame)img = cv2.imread('1.jpg')cv2.imshow('img',img)# 按下'q'就退出if k == ord('q'):#退出键breakif k == ord('d'):global dd = 1#作为画图触发条件# 释放画面cap.release()cv2.destroyAllWindows()def plot(tl,tr,bl,br):#画图并且展示函数# 得到坐标点在plot上进行绘画以及保存x = [tl[0], tr[0], br[0], bl[0], tl[0]]y = [640 - tl[1], 640 - tr[1], 640 - br[1], 640 - bl[1], 640 - tl[1]]plt.plot(x, y)plt.axhline(y=min(y), c="r", ls="--", lw=2)plt.title("rangel = {}".format(90 - rangle))plt.axis("equal")for a, b in zip(x, y):plt.text(a, b, (a, b), ha='center', va='bottom', fontsize=10)plt.savefig('zuobiao.png')#保存下来plt.clf()#清除plt.cla()fp = open('zuobiao.png', 'rb')img = Image.open(fp)#打开并且展示img.show()def midpoint(ptA, ptB):#计算坐标中点函数return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
def lunkuo(img):#检测轮廓start = time.time()#计算检测时间img1_ = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度img_ = cv2.GaussianBlur(img1_, (5, 5), 0)  # 高斯滤波去噪点img__ = cv2.Canny(img_, 75, 200)  # Canny边缘检测img__ = cv2.dilate(img__, None, iterations=1)#扩张img__ = cv2.erode(img__, None, iterations=1)#腐蚀# 轮廓检测cnts = cv2.findContours(img__.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)  # 检测出所有轮廓cnts = cnts[1] if imutils.is_cv3() else cnts[0]  # opencv4写法cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:]  # 排序得到前x个轮廓 可以根据图片自己设定#定义全局变量global screenCnt,box,ranglebox = 0rangle = 0# 我的摄像头分辨率为640*480 在摄像头中框出最合适检测的地方cv2.line(img, (595, 45), (595, 435),(255, 0, 255), 1)cv2.line(img, (45, 435), (595, 435),(255, 0, 255), 1)cv2.line(img, (45, 45), (45, 435),(255, 0, 255), 1)cv2.line(img, (45, 45), (595, 45),(255, 0, 255), 1)cv2.line(img, (45, 45), (595, 45),(255, 0, 255), 1)cv2.circle(img, (45, 45), 2, (255, 0, 0), -1)#中心点cv2.putText(img, "(0,0)",(45, 435), cv2.FONT_HERSHEY_SIMPLEX,0.5, (0, 244, 245), 2)#摄像头的坐标轴原点是在左上角 自己设定坐标轴原点并显示#遍历轮廓for c in cnts:# 计算轮廓近似peri = cv2.arcLength(c, True)# C表示输入的点集# epsilon表示从原始轮廓到近似轮廓的最大距离,它是一个准确度参数# True表示封闭的approx = cv2.approxPolyDP(c, 0.02 * peri, True)# 4个点的时候就拿出来 因为物品是矩阵形状if len(approx) == 4:screenCnt = approx  # 保存下来rangle = cv2.minAreaRect(screenCnt)[2]  # minAreaRect()函数返回角度 是最低的边到x水平坐标轴的角度box = cv2.cv.BoxPoints(cv2.minAreaRect(screenCnt)) if imutils.is_cv2() else cv2.boxPoints(cv2.minAreaRect(screenCnt))#得到四个最小矩阵的坐标点cv2.drawContours(img, [box.astype("int")], -1, (0, 255, 0), 2)#在图中画出来box = np.array(box, dtype="int")#转换类型(tl, tr, br, bl) = box#得到左上 右上 左下 右下的坐标点#计算中点(tltrX, tltrY) = midpoint(tl, tr)(blbrX, blbrY) = midpoint(bl, br)(tlblX, tlblY) = midpoint(tl, bl)(trbrX, trbrY) = midpoint(tr, br)#欧几里得度量dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))#固定摄像头及分辨率时 要想测出所测物品的长度 需要参照物 先使用已知宽度的矩形进行测量 得到 像素宽/实际宽 = 每宽多少像素 并保存下来# print('DB:',dB)# i = 1# if i == 1:#     pixelsPerMetric = dB / 3.4# print(pixelsPerMetric)# i += 1pixelsPerMetric = 35.15#得到的比率#分辨率除以比率可以得到摄像头测的实际范围长度# print('H:',640/pixelsPerMetric)# print('w:',480/pixelsPerMetric)if pixelsPerMetric != 0:#防止出现检测中没有实物得不到比例而发生除以0的错误#实际宽度dimA = dA / pixelsPerMetricdimB = dB / pixelsPerMetric#显示宽度cv2.putText(img, "{:.1f}cm".format(dimB),(int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)cv2.putText(img, "{:.1f}cm".format(dimA),(int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)#显示角度 此角度是经过变换后的 是我定义的坐标轴的矩形的最低点与x轴的夹角cv2.putText(img, "r:{:.1f}".format(90 - rangle),(int(tltrX + 20), int(tltrY + 20)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (225, 190, 0), 2)#画出点的坐标的直线并显示坐标点数据 容易观察夹角的位置 并且可以利用坐标计算夹角cv2.line(img, (int(bl[0]), int(bl[1])), (int(bl[0]), 435),(0, 244, 245), 1)cv2.putText(img, "({},{})".format(bl[0], 640 - bl[1]),(int(bl[0] - 20), 415), cv2.FONT_HERSHEY_SIMPLEX,0.4, (225, 190, 0), 1)cv2.line(img, (int(br[0]), int(br[1])), (int(br[0]), 435),(0, 244, 245), 1)cv2.putText(img, "({},{})".format(br[0], 640 - br[1]),(int(br[0]), 435), cv2.FONT_HERSHEY_SIMPLEX,0.4, (225, 190, 0), 1)cv2.line(img, (int(bl[0]), int(bl[1])), (int(595), int(bl[1])),(0, 244, 245), 1)end = time.time()#时间print("轮廓检测所用时间:{:.3f}ms".format((end - start) * 1000))global dif d == 1:#触发条件plot(tl, tr, bl, br)#画图d = 0#清除标志return  imgread_usb_capture()#开始

按下 d 结果如下:

opencv图片倾斜度检测(二)利用摄像头进行实时检测图片中物体并画出坐标轴和倾斜度相关推荐

  1. 使用face_recognition(二)目标人脸“实时”检测

    使用face_recognition(二)目标人脸"实时"检测 原文:https://blog.csdn.net/hehangjiang/article/details/78962 ...

  2. 睿智的目标检测20——利用mAP计算目标检测精确度

    睿智的目标检测20--利用mAP计算目标检测精确度 学习前言 GITHUB代码下载 知识储备 1.IOU的概念 2.TP TN FP FN的概念 3.precision(精确度)和recall(召回率 ...

  3. 人工智能Java SDK:读取本地摄像头,实时检测人脸

    人脸检测 人脸识别技术目前已经广泛应用于包括人脸门禁系统.刷脸支付等各行各业.随着人脸识别技术的提升,应用越来越广泛.目前中国的人脸识 别技术已经在世界水平上处于领先地位,在安防行业,国内主流安防厂家 ...

  4. python查看运行内存占用_利用Python如何实时检测自身内存占用

    前言 最近在做文本统计,用 Python 实现,遇到了一个比较有意思的难题--如何保存统计结果. 直接写入内存实在是放不下,十几个小时后内存耗尽,程序被迫关闭.如果直接写入数据库吧,每次写入又太慢了, ...

  5. python人脸实时检测_openCV+python实现人脸实时检测

    一.静态的图像人脸检测 import numpy as np import cv2 as cv path = 'haarcascade_frontalface_default.xml' face_ca ...

  6. JavaCV进阶opencv图像检测识别:摄像头图像人脸检测

    JavaCV免费教程目录: JavaCV入门教程(免费JavaCV教程) javacv实战专栏目录(2016年更新至今): JavaCV实战专栏文章目录(2016年更新至今) 2022年最新JavaC ...

  7. 目标检测——使用yolov6调用本地摄像头进行实时检测

    yolov6源码自带了图片目标检测推理功能: 当我们想进行摄像头实时检测识别的时候会有点不方便,根据源码的图片目标检测推理功能,我们进行稍作调整即可进行调用本地摄像头进行目标检测推理功能. 首先在源码 ...

  8. 轻量级实时目标检测网络--ThunderNet:轻量级实时检测网络

    网络的整体结构 网络的整体结构包括,backbone部分和detection 部分,骨干网络是SNet,这个网络i是基于shuffleNetV2进行修改得到的.网络的检测部分,利用了压缩的RPN网络, ...

  9. 电脑温度检测软件哪个好_实时检测Mac电脑的温度

    想要实时检测Mac电脑的温度吗?那就来试试这款Temperature Gauge Pro吧.Temperature Gauge Pro又名为TG Pro,是一款专业的Mac实时温度的软件.这款软件能够 ...

最新文章

  1. XGBoost算法原理解释(转载)
  2. android 沉浸式导航栏
  3. 单例带来的线程安全问题
  4. CentOS配置启动ssh与开机自启
  5. 如何在 SAP Commerce Cloud Portal 构建和部署 SAP Spartacus Storefront
  6. 独立版Jexus配置SSL,支持https访问
  7. 使用优化的基于模糊规则的特征选择技术和基于树的集成方法进行山洪敏感性建模--文献阅读
  8. springcloud断点续传源码_两套SpringCloud版的开源项目,项目源码和教程齐全
  9. 我的春Phone之行
  10. 有hcna证没有工作经验好找工作吗?
  11. GAN(生成对抗网络)有一本实战书出版了,了解下?
  12. 宝峰c1对讲机写频软件_宝峰888s写频软件
  13. 风变python怎么样_风变编程python到底怎么样?可以自学吗?
  14. python中compile函数
  15. android朋友圈九宫格图片尺寸,朋友圈图片尺寸多少厘米(附朋友圈发图技巧)...
  16. 加州房价篇 (三) : 模型的训练,评估和房价的预测
  17. Docker管理工具Web UI:DockerUI Shipyard /portainer
  18. 请问matlab里面exp函数怎么用啊,Matlab基本函数-exp函数
  19. viewpager 与 pageradapter
  20. 哲理故事三百篇(101-150)

热门文章

  1. 有关神经网络的训练算法,神经网络训练结果分析
  2. 【汇正财经】沪深创缩量震荡
  3. 计算机打不开运行软件怎么回事,电脑上软件打不开怎么办(电脑无法运行任何程序)...
  4. 学计算机专业可以学师范吗,师范学校的计算机专业,出来好找工作吗?有何方向?...
  5. 华容道6×6图解_全民主公华容道6怎么打 华容道6布阵图攻略详解
  6. 520 钻石争霸赛 2021 PTA 1-6题
  7. 什么时候用std::move()?
  8. 计算机辅助二维铣削加工,外形铣削加工计算机辅助制造.ppt
  9. Android中对Iconfont阿里图库的使用
  10. 古语云:工欲善其事必先利其器 最新、最全的 IntelliJ IDEA(2018.3.3) 的介绍、安装、破解、配置与使用