铁丝网交叉点坐标检测

铁丝网交叉点检测

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