基于OpenCV 在python中实现图像自动检测+手动截图


文章目录

  • 前言
  • 一、设计流程
    • 1.1图片读取
    • 1.2 图片处理
    • 1.3 图片裁剪及识别
  • 二、图像检测部分
  • 三、鼠标截图功能
  • 四、主函数
  • 五、结果展示
    • 5.1 原图
    • 5.2 图片hsv阈值筛选
    • 5.3 滤波
    • 5.4 灰度
    • 5.5 阈值化(二值化)
    • 5.6 腐蚀
    • 5.7 膨胀
    • 5.8 边缘检测结果
    • 5.9 最终结果
    • 5.10 视频演示
  • 六、总结


前言

提示:这里可以添加本文要记录的大概内容:

针对图像检测技术的发展,自动化的需求,因此本文开发了一种基于OpenCV图像检测及图像分割技术。


提示:以下是本篇文章正文内容,下面案例可供参考

一、设计流程

基于OpenCV 在python中实现图像自动检测+手动截图_第1张图片

1.1图片读取

基于OpenCV 在python中实现图像自动检测+手动截图_第2张图片

1.2 图片处理

基于OpenCV 在python中实现图像自动检测+手动截图_第3张图片

1.3 图片裁剪及识别

基于OpenCV 在python中实现图像自动检测+手动截图_第4张图片

二、图像检测部分

# 检测红色的阈值
def detect(path_input,path_save):
    '''
    param:
    path_input = 输入图片路径
    path_save = 保存路径
    function:
    处理图片,对图片进行灰度,滤波,二值化,腐蚀膨胀等处理,并裁剪后保存
    '''
    global img , img_name
    img_name = path_save
    img = cv2.imread(path_input)
    img=cv2.resize(img,(img.shape[1]//4,img.shape[0]//4))
    cv2.namedWindow('photo',0)              # 打开待截图窗口 ,此窗口可以对图片操作
    cv2.resizeWindow("photo", img.shape[1], img.shape[0])
    cv2.imshow('photo', img)
    cv2.setMouseCallback('photo', on_mouse) # 回调函数
    # 防止图片分辨率太大,最后保存失败,因此重置分辨率,通常横拍的图片会失败
    
    
    
    
    lower_blue=np.array([0,20,170])
    upper_blue=np.array([15,200,255])
    
    # change to hsv model
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    
    
    # get mask
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    
    # detect blue
    image = cv2.bitwise_and(img, img, mask=mask)
    #cv2.imshow('detect',image)
    
    # 滤波
    image = cv2.blur(image, (9,9))
    #cv2.imshow('blur',image)
    
    
    # 灰度
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    '''
    gradX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
    gradY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)
    cv2.imshow('',gray)
    cv2.imshow('1',gradX)
    cv2.imshow('2',gradY)
    
    
    
    
    # subtract the y-gradient from the x-gradient
    # 图片加减法
    
    gradient = cv2.subtract(gradX, gradY)
    cv2.imshow('subtract',gradient)
    '''
    #dst1 = cv2.add(gradX, gradY)
    #cv2.imshow('add',dst1)
    
    # 转换数据为uint8 
    gradient = cv2.convertScaleAbs(gray)
    #cv2.imshow('gray',gray)
    
    '''
    # blur and threshold the image
    # 均值滤波 高斯
    blurred = cv2.blur(gradient, (3,3))
    cv2.imshow('blur',blurred)
    
    blurred=cv2.GaussianBlur(gradient,(5,5),0,0)
    cv2.imshow('GaussianBlur',blurred)
    '''
    
    
    # 二值化
    (_, thresh) = cv2.threshold(gradient,70, 255, cv2.THRESH_BINARY)
    #cv2.imshow('threshold',thresh)
    closed = thresh.copy()
    
    # 产生卷积核
    
    '''
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,15))
    # 形态滤波
    closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    cv2.imshow('CLOSE',closed)
    '''
    '''
    closed = cv2.morphologyEx(thresh, cv2.MORPH_TOPHAT, kernel)
    cv2.imshow('TOPHAT',closed)
    
    closed = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    closed_2 = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
    closed_4 = cv2.morphologyEx(thresh, cv2.MORPH_BLACKHAT, kernel)
    cv2.imshow('OPEN',closed)
    cv2.imshow('_GRADIENT',closed_2)
    cv2.imshow('BLACKHAT',closed_4)
    
    '''
    
    # perform a series of erosions and dilations
    #形态学腐蚀与膨胀
    closed = cv2.erode(closed, (1,1), iterations=3)
    #cv2.imshow('erode',closed)
    
    closed = cv2.dilate(closed,(3,3), iterations=9)
    #cv2.imshow('dilate',closed)
    
    
    (cnts, a) = cv2.findContours(closed.copy(), cv2.RETR_LIST,
                                 cv2.CHAIN_APPROX_SIMPLE)
    #c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
    
    c = max(cnts, key=cv2.contourArea)
    # compute the rotated bounding box of the largest contour
    rect = cv2.minAreaRect(c)
    
    box = np.int0(cv2.boxPoints(rect)) # 矩形的四个点
     
    # draw a bounding box arounded the detected barcode and display the image
    cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
    #cv2.imshow("Image", image)
    cv2.imwrite('draw.jpg',image)
    #cv2.waitKey(0)
    Xs = np.array([i[0] for i in box])
    Ys = np.array([i[1] for i in box])
    # 将矩形整形到 图片尺寸中,防止超边
    Xs[Xs < 0] = 0
    Xs[Xs > img.shape[1]] = img.shape[1]
    Ys[Ys < 0] = 0
    Ys[Ys > img.shape[0]] = img.shape[0]
    
    x1 = min(Xs)
    x2 = max(Xs)
    y1 = min(Ys)
    y2 = max(Ys)
    cropImg = img[y1:y2, x1:x2]
    
    cv2.imwrite(path_save, cropImg) # 保存
    cv2.imshow('AOTUcut',cropImg)


文中相关参数可以实验性地更改,比如滤波值,腐蚀膨胀参数等。
这里需要所检测物体的hsv颜色阈值,hsv的阈值检测程序如下。

import cv2
import numpy as np
#   读 取 图 片
img = cv2.imread('38.jpg')  # 直接读为灰度图像

height, width = img.shape[:2]
size = (int(width //4), int(height //4))  # 缩小或者放大图片显示大小
img = cv2.resize(img, size, interpolation=cv2.INTER_AREA)
#BGR转化为HSV
HSV=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#鼠标点击响应事件


# 当鼠标按下时变为True
drawing=False
ix,iy=-1,-1

def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing
    # 当按下左键是返回起始位置坐标
    if event==cv2.EVENT_LBUTTONDOWN:
        drawing=True
        ix,iy=x,y
    # 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
    elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
        if drawing==True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
    # 当鼠标松开 停止绘画
    elif event==cv2.EVENT_LBUTTONUP:
        drawing==False





def getposHsv(event,x,y,flags,param):
    if event==cv2.EVENT_LBUTTONDOWN:
        print("HSV is",HSV[y,x],type(HSV),HSV[y,x][0],HSV[y,x][1],HSV[y,x][2])
        param = param.append([HSV[y,x][0], HSV[y,x][1], HSV[y,x][2]])
        

def getposBgr(event,x,y,flags,param):
    if event==cv2.EVENT_LBUTTONDOWN:
        print("Bgr is",img[y,x])

h=[]

cv2.imshow("imageHSV",HSV)
cv2.imshow('image',img)
#cv2.setMouseCallback("imageHSV",getposHsv,param =h)
#cv2.setMouseCallback("image",getposBgr)
cv2.setMouseCallback("cut",draw_circle)
cv2.waitKey(0)

将待测图片加载后运行程序即可。

三、鼠标截图功能

def on_mouse(event, x, y, flags, param):
    global point1, point2
    img2 = img.copy()
    if event == cv2.EVENT_LBUTTONDOWN:                                      # 左键点击时
        point1 = (x,y)                                                      # 记录第一个点
        cv2.circle(img2, point1, 10, (0,255,0), 3)                          # 第一个点画园 图像,圆心,半径
        cv2.imshow('photo', img2)                                           # 展示画园时的画面
    elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON): # 按住左键拖曳 当鼠标左键按住时
        cv2.rectangle(img2, point1, (x,y), (255,0,0), 3)                    # 画矩形
        cv2.imshow('photo', img2)                                           # 展示画矩形时的画面
    elif event == cv2.EVENT_LBUTTONUP:                                      # 左键释放 当鼠标左键松开时
        point2 = (x,y)                                                      # 记录第二个点
        cv2.rectangle(img2, point1, point2, (0,0,255), 3)                   # 画框 变色
        cv2.imshow('photo', img2)                                           # 展示
        min_x = min(point1[0],point2[0])                                    # 赋值
        min_y = min(point1[1],point2[1])
        width = abs(point1[0] - point2[0])
        height = abs(point1[1] -point2[1])
        cut_img = img[min_y:min_y+height, min_x:min_x+width]
        cv2.imwrite(img_name, cut_img)
        cv2.imshow('HAND cut',cut_img)

四、主函数

if __name__ == '__main__':
    path = r'photos'                                     # 读取位置
    save = r'save'                                       # 保存位置
    # 遍历文件
    num = 0
    for file in os.listdir(path):
        path_img = os.path.join(path,file)              # 读取路径
        save_img = os.path.join(save,file)              # 保存路径
        if not os.path.exists('{}/{}.jpg'.format(path,num)): # 如果文件不存在 则重新命名
             os.rename(path_img, '{}/{}.jpg'.format(path,num))
             print('',path_img, '更名为:' , '{}/{}.jpg'.format(path,num))
             detect(path_input='{}/{}.jpg'.format(path,num),path_save='{}/{}.jpg'.format(save,num))
             cv2.waitKey(0)
             cv2.destroyAllWindows()
        else:
            print(path_img)
            detect(path_input=path_img,path_save=save_img)
            cv2.waitKey(0) 
            cv2.destroyAllWindows()
        num+=1
        
        
    
    print('-----------------全部处理完毕---------------------\n')
    print('总计 %s 张'%num)

对path路径里的图片进行遍历读取,并自动识别后裁剪,保存到save文件夹中。

五、结果展示

5.1 原图

基于OpenCV 在python中实现图像自动检测+手动截图_第5张图片

5.2 图片hsv阈值筛选

基于OpenCV 在python中实现图像自动检测+手动截图_第6张图片

5.3 滤波

基于OpenCV 在python中实现图像自动检测+手动截图_第7张图片

5.4 灰度

基于OpenCV 在python中实现图像自动检测+手动截图_第8张图片

5.5 阈值化(二值化)

基于OpenCV 在python中实现图像自动检测+手动截图_第9张图片

5.6 腐蚀

基于OpenCV 在python中实现图像自动检测+手动截图_第10张图片

5.7 膨胀

基于OpenCV 在python中实现图像自动检测+手动截图_第11张图片

5.8 边缘检测结果

基于OpenCV 在python中实现图像自动检测+手动截图_第12张图片

5.9 最终结果

5.10 视频演示

暂无,待上传

六、总结

本次批量处理的检测合格率为45/72,针对不合格的也作出了针对性补偿,如避免遮挡,保持间隔等。并开发了手动截图的功能,以此保证本项目功能的全面实现。

你可能感兴趣的:(笔记,opencv,python,计算机视觉)