Toriyung

导航

Opencv Q&A_5

2022/03/09-2022/03/10

图像操作的几类函数实践

 

代码_main_1

def nothing(x):
    pass

weigh = 640
height = 720

img = cv.imread('D:\work\\automation\Skill\Python\pythonWORK\cv\material\\book1.jpg')
img = cv.resize(img,(0,0),None,0.4,0.4)

## 创建滑条
cv.namedWindow('img')   #滑条所在窗口
cv.createTrackbar('thres1', 'img', 50, 255, nothing)    #滑条名称,所在窗口,下上阈值,执行动作函数(自定义)
cv.createTrackbar('thres2', 'img', 50, 255, nothing)


while True:
    thres1 = cv.getTrackbarPos('thres1', 'img')
    thres2 = cv.getTrackbarPos('thres2', 'img')
    kernel = np.ones((5,5))

    img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

    img_erode = cv.erode(img_gray,kernel,iterations=3)  #腐蚀,黑色吞噬白色
    img_dial = cv.dilate(img_gray,kernel,iterations=3)  #膨胀,白色吞噬黑色
    img_ex = cv.morphologyEx(img_gray,cv.MORPH_OPEN,kernel,iterations=3)    #开闭操作:重点突出黑或白。开:先腐后膨;闭:先膨后腐。

    img_gaussian = cv.GaussianBlur(img_gray,(1,1),0)     #高斯模糊,参数为x轴和y轴方向标准差计算,必须为奇数,越大模糊效果越强
    img_canny = cv.Canny(img_gray,thres1,thres2)      #计算出边缘(下上阈值),大于阈值算边缘

    cv.imshow('img', img_canny)
    cv.waitKey(1)

 

运行效果1

图一 腐蚀

 

图二  膨胀

 

 

图三   开操作

 

 

 

图四   高斯模糊

 

 

 图五   canny

 

 

 

 代码_main_2

while True:
    thres1 = cv.getTrackbarPos('thres1', 'img')
    thres2 = cv.getTrackbarPos('thres2', 'img')
    thres3 = cv.getTrackbarPos('thres3', 'img')
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    img_canny = cv.Canny(img_gray, 50, 200)  # 计算出边缘(下上阈值),大于阈值算边缘

    ## 找轮廓(所有和最大)
    img_contour, hierarchy = cv.findContours(img_canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)  # 找到所有轮廓
    img_contour = utlis.findBiggestContour(img_contour)  # 找到最大边缘折角坐标
    ct = utlis.reorder(img_contour,2)   #重新排序坐标位置
    ct = np.array([ct], np.int32)     #转化成整数数组并转化成列表
    cv.drawContours(img,img_contour,-1,(0,255,0),10)    #四个角定位点
    cv.polylines(img,ct,True,(0,255,0),2)   #多边形

    ##透视
    matrix = cv.getPerspectiveTransform(np.float32(utlis.reorder(img_contour,1)), #   获取透视转换配置数据(待转换坐标(↖↙↘↗),转换后坐标)
                                        np.float32([[0, 0], [0, height], [weigh, 0], [weigh, height]]))
    pers = cv.warpPerspective(img_gray, matrix, (weigh, height))     #透视操作(操作图片,配置数据,显示大小(全显示则需和坐标))

    ## 自适应阈值:对不同区域取不同阈值(如在采光条件不同的情况下)
    adapt = cv.adaptiveThreshold(pers, 200, 1, 0, 5, 5)  # 自适应阈值(阈值上限,自适应阈值算法,阈值类型,阈值块大小,算法相关的常数C)

    cv.imshow('img', img)
    cv.waitKey(0)

 

运行效果2

 

图六  最大边框

 

 

图七  透视

 

 

图八  自适应阈值

 

 

代码_utlis

import cv2 as cv


def findBiggestContour(contours):
    ## 找到最大轮廓
    max_contour = []
    contour_max = 0
    for contour in contours:
        area = cv.contourArea(contour)  #获得轮廓面积
        print(area)
        length = cv.arcLength(contour,True)     #获得轮廓周长(是否闭合)
        poly = cv.approxPolyDP(contour,0.02*length,True)    #将曲线拟合为多边形,输出多边形折点坐标(轮廓距离物体距离(越小越好),是否闭合)
        if area >= 5000 and len(poly) == 4:    #面积大于5000且多边形条数为4(矩形)
            if area > contour_max:
                contour_max = area
                max_contour = poly
    return max_contour

def reorder(location,mod):
    ## 重新编排坐标信息顺序
    if mod == 1:    #↖↙↗↘
        list = []
        list.append(location[0][0])
        list.append(location[1][0])
        list.append(location[3][0])
        list.append(location[2][0])
    if mod == 2:    #↖↗↘↙
        list = []
        list.append(location[0][0])
        list.append(location[3][0])
        list.append(location[2][0])
        list.append(location[1][0])

    return list

 

遇到的问题

Q1:import 同文件夹下的自定义包失败

A1:在本目录设置:mark this directory as source root

Q2:部分函数解析

A2:

  1. cv.approxPolyDP():将曲线拟合为多边形,返回多边形折点坐标,需要选择判断对象是闭合曲线还是非闭合曲线

  2. cv.getPerspectiveTransform():获取透视转换配置数据,输入坐标依次为:↖↙↗↘,和cv.polylines()不同,所以使用自定义函数utlis.reorder()进行区分转换

      cv.warpPerspective():进行透视转换,需注意输入dsize参数--展示大小,如果想要展示所有内容需>=图片大小

  3. cv.adaptiveThreshold():自适应阈值,弥补了图片不同区域不同光量情况下普通阈值操作的不足。基本思想是不同区域计算给予不同阈值

Q3:canny()检测边缘效果差

A3:opencv中canny()没有前面的降噪过程,需要先进行模糊(一般选择高斯模糊),效果很大程度取决于模糊。

posted on 2022-03-11 23:42  Toriyung  阅读(35)  评论(0编辑  收藏  举报