vieyahn2017 / pypy

python trial collections
1 stars 1 forks source link

划痕识别 #9

Open vieyahn2017 opened 1 year ago

vieyahn2017 commented 1 year ago

https://blog.csdn.net/u014072827/article/details/117923494

vieyahn2017 commented 1 year ago

import cv2
import numpy as np

#print(cv2.__version__)  # 4.5.5
minThres = 6

# 读取图像1
BASEDIR = 'D:\\jav\\py\\'
img1 = cv2.imread(BASEDIR + '4.jpg')
img2 = cv2.imread(BASEDIR + '4.jpg')
#cv2.imshow('raw', img1)
# 中值滤波
img1 = cv2.medianBlur(img1, 15)
#cv2.imshow('mblur', img1)

# 图像差分
diff = cv2.absdiff(img1, img2)
#cv2.imshow('diff', diff)  # 结果图

gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
# 二值化
_, thres = cv2.threshold(gray, minThres, 255, cv2.THRESH_BINARY)
#cv2.imshow('thres', thres)

# 查找轮廓
contours, hierarchy = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# 输出轮廓个数
print(len(contours))

def show_image(image, title="img"):
    cv2.namedWindow(title, 0)
    cv2.imshow(title, image)
    cv2.waitKey(0)

line_rgb = (0, 255, 0)
rows, cols = img2.shape[:2]
ii=0
for i in range(0, len(contours)):
    length = cv2.arcLength(contours[i], True)
    area = cv2.contourArea(contours[i])
    # 通过轮廓长度筛选
    if length > 1000:
        print((i, length, area))
        ii += 1
        cnt = contours[i]
        # print(cnt)
        # approx = cv2.approxPolyDP(cnt, 2, True)
        cv2.drawContours(img2, cnt, -1, (0, 0, 255), 2)
        # cv2.drawContours(img2, approx, -1, (0, 255, 0), 2)

        # 最优拟合直线
        [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01)
        lefty = int((-x*vy/vx) + y)
        righty = int(((cols-x)*vy/vx) + y)
        print((cols-1, righty), (0, lefty))
        if ii == 1:
            # cv2.line(img2, (cols-1, righty), (0, lefty), line_rgb, 2)
            cv2.line(img2, (1279, 183), (0, -893) , line_rgb, 2)
            # cv2.line(img2, (1279, 183), (0, -903) , line_rgb, 2)
        if ii == 2: # 拆分中间那个(ii=2)
            # cv2.line(img2, (cols-1, righty), (0, lefty), line_rgb, 2)  # (1279, 536) (0, -728)
            cv2.line(img2, (1278, 554), (788, 0) , line_rgb, 2) # 来自PS的坐标
            cv2.line(img2, (1274, 525), (681, 0) , line_rgb, 2)
        if ii == 3:
            cv2.line(img2, (cols-1, righty), (0, lefty), line_rgb, 2)

print(ii)

cv2.imshow('result', img2)  # 结果图
#cv2.waitKey(0)

lower = line_rgb  # lower bound for each channel
upper = line_rgb  # upper bound for each channel
mask = cv2.inRange(img2, lower, upper)
cv2.imshow('mask', mask)  # 结果图
cv2.waitKey(0)
cv2.imwrite(BASEDIR + '4-mask.jpg', mask)
vieyahn2017 commented 1 year ago

直线检测

https://blog.csdn.net/weixin_44145452/article/details/112767669

vieyahn2017 commented 1 year ago

import cv2
import numpy as np

def show_image(image, title="img"):
    cv2.namedWindow(title, 0)
    cv2.imshow(title, image)
    cv2.waitKey(0)

def line_detection(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150, apertureSize=3)#apertureSize,Canny边缘检测梯度那一步,窗口大小是3   apertureSize是sobel算子大小,只能为1,3,5,7
    lines = cv2.HoughLines(edges, 1, np.pi/180, 200) #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
    for line in lines:
        # print(type(lines)) # <class 'numpy.ndarray'>
        rho, theta = line[0]
        #获取极值ρ长度和θ角度
        a = np.cos(theta) #获取角度cos值
        b = np.sin(theta)#获取角度sin值
        x0 = a * rho #获取x轴值
        y0 = b * rho #获取y轴值  x0和y0是直线的中点
        x1 = int(x0 + 1000 * (-b)) #获取这条直线最大值点x1
        y1 = int(y0 + 1000 * (a)) #获取这条直线最大值点y1
        x2 = int(x0 - 1000 * (-b)) #获取这条直线最小值点x2
        y2 = int(y0 - 1000 * (a)) #获取这条直线最小值点y2  其中*1000是内部规则
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) #开始划线
    # cv2.imshow(image, "image_lines")
    show_image(image, "image_lines")

def cal_line_and_to_p2(x1, y1, x2, y2):
    p1 = [x1, y1]
    p2 = [x2, y2]
    slope = (y2-y1)/(x2-x1)
    # slope, _ = np.polyfit(p1, p2, 1)
    # print(("===", p1, p2, slope))
    return p1, p2, slope

def line_detect_possible_demo(image):
    mask_rgb = (0, 255, 0)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150, apertureSize=3)  # apertureSize,Canny边缘检测梯度那一步,窗口大小是3
    lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50, maxLineGap=20)  #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
    #minLineLength-线的最短长度,比这个线短的都会被忽略
    #maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。
    for line in lines:
        # print(type(lines)) # <class 'numpy.ndarray'>
        # print(line)
        x1, y1, x2, y2 = line[0]
        p1, p2, slope = cal_line_and_to_p2(x1, y1, x2, y2)
        if slope > 5 and slope < 7:
            cv2.line(image, p1, p2, mask_rgb, 2)
            print(p1, p2, slope)

    # todo 手动加入点
    # cv2.imshow("line_detect_possible_demo", image)
    show_image(image, "line_detect_possible_demo")
    lower = mask_rgb  # lower bound for each channel
    upper = mask_rgb  # upper bound for each channel
    mask = cv2.inRange(image, lower, upper)
    show_image(mask, "mask")
    return mask

BASEDIR = 'D:\\jav\\py\\'
src = cv2.imread(BASEDIR + '5.jpg')

#cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
# cv2.namedWindow("input image", 0)
# cv2.imshow("input image", src)

# line_detection(src)

result = line_detect_possible_demo(src)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
cv2.imwrite(BASEDIR + '5-mask.jpg', result)