题目描述 利用opencv
或其他工具编写程序实现宽度测量。
实现过程
# -*- coding: utf-8 -*-
'''
作者 : 丁毅
开发时间 : 2021/4/14 14:52
'''
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
#用于给图片添加中文字符
def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):
# 判断是否OpenCV图片类型
if (isinstance(img, np.ndarray)):
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
# 字体的格式
fontStyle=ImageFont.truetype("font/simsun.ttc",textSize, encoding="utf-8")
# 绘制文本
draw.text((left, top), text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
#读取图片
img = cv2.imread(r"C:\Users\pc\Desktop\gongjian1-2.bmp")
cv2.imshow("image",img)
#截取目标区域
x0, y0, w0, h0 = cv2.selectROI(windowName="image", img=img, showCrosshair=False, fromCenter=False)
cut_img = img[y0: y0 + h0, x0: x0 + w0]
#二值化处理
ret, th = cv2.threshold(cut_img, 80, 255, cv2.THRESH_BINARY_INV)
# 边缘检测
img1 = cv2.Canny(cut_img, 100, 200)
# 反色
img1 = 255 - cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
# 灰度图
gray_img = cv2.cvtColor(255 - th, cv2.COLOR_RGB2GRAY)
#获得轮廓,用一个矩形框出物体的轮廓
contours, hierarchy = cv2.findContours(gray_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0])
img[y0: y0 + h0, x0: x0 + w0] = img1
cv2.imshow('image2', img)
# 绘制直线
cv2.line(img1, (x, y), (x, y + h), (255, 0, 0), 2, 5) # 左侧线
cv2.line(img1, (x + w, y), (x + w, y + h), (255, 0, 0), 2, 5) # 右侧线
img[y0: y0 + h0, x0: x0 + w0] = img1
cv2.imshow('image3', img)
#图片上添加宽度大小
img = cv2ImgAddText(img, '宽度%d'%h, 20, 20, (255, 0, 0), 25) # 在图片上显示文字
cv2.imshow('image4', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果
问题及解决 1.使用鼠标截取目标区域 参考链接 方式:selectROI(windowName, img, showCrosshair=None, fromCenter=None):
- 参数
windowName
:选择的区域被显示在的窗口的名字 - 参数
img
:要在什么图片上选择ROI - 参数
showCrosshair
:是否在矩形框里画十字线. - 参数
fromCenter
:是否是从矩形框的中心开始画
该方式可以直接通过鼠标来操作,选取指定的区域,选取后点击回车即可运行之后的代码。
2.检测物体的轮廓 参考链接 方式: cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])
- 第一个参数是指明在哪幅图像上绘制轮廓;
- 第二个参数是轮廓本身,在
Python
中是一个list
。 - 第三个参数指定绘制轮廓
list
中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness
表明轮廓线的宽度,如果是-1(cv2.FILLED
),则为填充模式。
3.用矩形框出物体的轮廓 参考链接 示例效果图:
方式:cv2.boundingRect(img) 传入img
:二值图 返回值:x
, y
, w
, h
,(x,y)
是矩阵左上角的坐标,w
,h
是矩阵的宽与高。
4.绘制直线的方法 参考链接 示例: line(frame, beginPoint, endPoint, Scalar(0, 0, 255), 2); 画一条直线,起点为beginPoint
,终点是endPoint
,颜色是红色,线宽是2,shift
为默认值。beginPoint
与endPoint
是坐标值。