import cv2
import numpy as np
import random as rng
import matplotlib.pyplot as plt
def ExtractionColor(image):
"""
图片预处理方法一:提取图片中特定的色彩部分
1.提取图片中的黑色部分
"""
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
low_hsv = np.array([0, 0, 0])
high_hsv = np.array([180, 255, 143])
mask = cv2.inRange(hsv, lowerb=low_hsv, upperb=high_hsv)
return mask
def FindOutline(mask):
"""
2.查找轮廓,
输出找到的轮廓个数
"""
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#contours, hierarchy = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
print("find", len(contours), "contours")
return contours,hierarchy
def drawMyContours(winName, image, contours, draw_on_blank):
"""
3.绘制轮廓函数
自定义绘制轮廓的函数(为简化操作)
输入1:winName:窗口名
输入2:image:原图
输入3:contours:轮廓
输入4:draw_on_blank:绘制方式,True在白底上绘制,False:在原图image上绘制
"""
if (draw_on_blank): # 在白底上绘制轮廓
temp = np.ones(image.shape, dtype=np.uint8) * 255
cv2.drawContours(temp, contours, -1, (0, 0, 0), 2)
else:
temp = image.copy()
cv2.drawContours(temp, contours, -1, (0, 0, 255), 2)
# cv2.namedWindow(winNamet, cv2.WINDOW_GUI_NORMAL)
cv2.imshow(winName, temp)
return winName
def draw_Contours( mask, contours, hierarchy):
"""
4.绘制原始轮廓
"""
cv2.namedWindow("find contours", cv2.WINDOW_GUI_NORMAL)
drawing = np.zeros((mask.shape[0], mask.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (rng.randint(256,256), rng.randint(256,256), rng.randint(256,256))
cv2.drawContours(drawing, contours, i, color, 2, cv2.LINE_8, hierarchy, 0)
return drawing
def delet_contours(contours, delete_list):
"""
5.删除指定轮廓
自定义函数:用于删除列表指定序号的轮廓
输入 1:contours:原始轮廓
输入 2:delete_list:待删除轮廓序号列表
返回值:contours:筛选后轮廓
"""
delta = 0
for i in range(len(delete_list)):
# print("i= ", i)
del contours[delete_list[i] - delta]
delta = delta + 1
return contours
def Gauge_Length(contours):
"""
6.筛选轮廓
计算每个轮廓长度
"""
lengths = list()
for i in range(len(contours)):
length = cv2.arcLength(contours[i], True)
lengths.append(length)
print("轮廓%d 的周长: %d" % (i, length))
# 使用轮廓长度滤波
min_size = 20
max_size = 200
delete_list = []
for i in range(len(contours)):
if (cv2.arcLength(contours[i], True) < min_size) or (cv2.arcLength(contours[i], True) > max_size):
delete_list.append(i)
# 根据列表序号删除不符合要求的轮廓
# contours = delet_contours(contours, delete_list)#筛选后的轮廓
print("find", len(contours), "contours left after length filter")#打印筛选后的轮廓
# cv2.namedWindow('contours after length filtering', cv2.WINDOW_GUI_NORMAL)
# drawMyContours("contours after length filtering", image, contours, False)
def Draw_Orthogon(image,contours):
"""
7.形状描述子
最小覆盖矩形,求出矩形四点坐标,并输出矩形左上角坐标并标点
"""
result = image.copy()
for i in range(len(contours)):
rect = cv2.minAreaRect(contours[i])
box = cv2.boxPoints(rect)
box = np.int0(box)
draw_rect = cv2.drawContours(image.copy(), [box], -1, (0, 0, 255), 2)
#左上角坐标值
pt = (box[1][0], box[1][1])
#画线
print("box_{}:,左上角横坐标为{}\n".format(i, box[1][0]))
plt.plot(box[1][0], box[1][1], 'r-o')
#画红点
cv2.circle(result, pt, 2, (0, 0, 255), 2)
text = "(" + str(pt[0]) + ", " + str(pt[1]) + ")"
# cv2.putText(result, text, (pt[0] + 10, pt[1] + 10), cv2.FONT_HERSHEY_PLAIN, 1.5, (255, 255, 255), 1, 8, 0)
print("box_{}:{},左上角坐标为{}\n".format(i, box, box[1]))
image = draw_rect
plt.show()
# cv2.imshow("draw_rect", draw_rect)
cv2.namedWindow('only_res', cv2.WINDOW_GUI_NORMAL)
cv2.imshow("only_res", result)
def Find_Coordinates(image,contours):
"""
8.输出铁丝网每条线的横纵坐标
"""
value_a = []
value_b = []
result = image.copy()
# n = 0
for i in range(len(contours)):
rect = cv2.minAreaRect(contours[i])
box = cv2.boxPoints(rect)
box = np.int0(box)
a = box[1][1]
for j in range(len(contours)):
rect = cv2.minAreaRect(contours[j])
box = cv2.boxPoints(rect)
box = np.int0(box)
if (a == box[1][1]):
print("box_{}:左上角横坐标为{}\n".format(j, box[1][0]))
print("box_{}:左上角纵坐标为{}\n".format(j, box[1][1]))
x = box[1][0]
y = box[1][1]
value_a.append(x)
value_b.append(y)
# 画红点
pt = ( x , y )
cv2.circle(result, pt, 2, (0, 0, 255), 2)
# plt.plot(value_a, value_b, 'r-o')
# if (i == 100):
# break
# plt.plot(x, box[1][1], linewidth=1, color='red')
# print(value_a)
# print(value_b)
# plt.show()
# cv2.namedWindow('结果', cv2.WINDOW_GUI_NORMAL)
# cv2.imshow("结果", result)
return result
# plt.plot(box[1][0], box[1][1], 'r-o')
# plt.show()
def Draw_End(image,contours):
"""
9.标记左上角坐标点
(轮廓和点在同一张图中显示)
"""
for i in range(len(contours)):
rect = cv2.minAreaRect(contours[i])
box = cv2.boxPoints(rect)
box = np.int0(box)
draw_rect = cv2.drawContours(image.copy(), [box], -1, (0, 0, 255), 2)
# 左上角坐标值
pt = (box[1][0], box[1][1])
# 画点
# circle = cv2.circle(draw_rect.copy(), pt, 2, (0, 255, 0), 2)
text = "(" + str(pt[0]) + ", " + str(pt[1]) + ")"
# all = cv2.putText(circle.copy(), text, (pt[0] + 10, pt[1] + 10), cv2.FONT_HERSHEY_PLAIN, 1.5, (255, 255, 255), 1, 8, 0)
all = cv2.putText(draw_rect.copy(), text, (pt[0] + 10, pt[1] + 10), cv2.FONT_HERSHEY_PLAIN, 1.5, (255, 255, 255), 1, 8, 0)
image = all
# cv2.namedWindow('all_res', cv2.WINDOW_GUI_NORMAL)
# cv2.imshow("all_res", all)
if __name__ == '__main__':
rng.seed(12345)
image = cv2.imread("******.jpg")
print(image.shape)
mask = ExtractionColor(image)
cv2.namedWindow('find_Color', cv2.WINDOW_GUI_NORMAL)
cv2.imshow("find_Color", mask)
contours, hierarchy = FindOutline(mask)
drawMyContours("find contours", image, contours, True)
drawing = draw_Contours(mask, contours, hierarchy)
cv2.namedWindow('Contours', cv2.WINDOW_GUI_NORMAL)
cv2.imshow('Contours', drawing)
contours = delet_contours(contours,1)
Gauge_Length(contours)
Draw_Orthogon(image, contours)
result = Find_Coordinates(image, contours)
cv2.imwrite("****.png", result)
Draw_End(image, contours)
#防止窗口闪现
cv2.waitKey()
#销毁所有窗口
cv2.destroyAllWindows()
铁丝网交叉点坐标检测
猜你喜欢
转载自blog.csdn.net/weixin_45994963/article/details/126382291
今日推荐
周排行