美文网首页
2019-06-03 OpenCV学习

2019-06-03 OpenCV学习

作者: 毛十三_ | 来源:发表于2019-06-24 16:03 被阅读0次

21直线检测

霍夫直线变换用来做直线检测,前提条件是边缘检测已完成。

import cv2 as cv
import numpy as np

def line_detection(image):
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    edges = cv.Canny(gray,50,150,apertureSize=3)
    lines = cv.HoughLines(edges, 1, np.pi/180, 200)
    for line in lines:
        rho, theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0+1000*(-b))
        y1 = int(y0+1000*(a))
        x2 = int(x0-1000*(-b))
        y2 = int(y0-1000*(a))
        cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)
    cv.imshow("image_line", image)
def line_detect_possible_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    edges = cv.Canny(gray, 50, 150, apertureSize=3)
    lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10)
    for line in lines:
        x1,y1,x2,y2 = line[0]
        cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)
    cv.imshow("line_detect_possible_demo", image)


22圆检测

霍夫圆变换原理:

  • 从平面坐标到极坐标转换,三个参数C(x0,y0,r),其中x0y0是圆心
  • 假设平面坐标上任意一个圆上的点转换到极坐标中C(x0,y0,r)处有最大值,霍夫变换正是利用这一原理来检测圆的。

现实考量:
  • 霍夫检测噪声敏感,所以首先对图像做中值滤波。
  • 基于效率考虑,分为两步:
    检测边缘,发现可能的圆心。
    基于上一步,从候选圆心开始计算最佳半径大小。
import cv2 as cv
import numpy as np
def Hough_Circle_demo(image):
    dst = cv.pyrMeanShiftFiltering(image, 10, 100)
    cimage = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
    circles = cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20,param1=50, param2=20, minRadius=0, maxRadius=0)
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        cv.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 2)
        cv.circle(image, (i[0], i[1]), 2, (0, 0, 255), 3)
    cv.imshow("circles",image)

print("=====Hello Python=====")
image = cv.imread("opencv_sources/circle.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
Hough_Circle_demo(image)
cv.waitKey(0)
cv.destroyAllWindows()

23轮廓发现

是基于图像边缘提取的基础寻找对象轮廓的方法。

import cv2 as cv
def contours_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary image",binary)
    cloneImage, contours, heriachy  = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    for i , contour in enumerate(contours):
        cv.drawContours(image, contours, i, (0,0,255), 2)
        print(i)
    cv.imshow("detect contours",image)
print("=====Hello Python=====")
image = cv.imread("opencv_sources/circle.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
contours_demo(image)
cv.waitKey(0)
cv.destroyAllWindows()

canny轮廓提取的效果
import cv2 as cv
import numpy as np
def edge_demo(image):
    blured = cv.GaussianBlur(image, (3, 3), 0) # 高斯模糊降低噪声
    gray = cv.cvtColor(blured, cv.COLOR_BGR2GRAY)
    # x gradient
    xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0)
    # y gradient
    ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
    # edge
    edge_output = cv.Canny(xgrad, ygrad, 50, 150) # 低阈值50高阈值150
    return  edge_output
def contours_demo(image):
    binary = edge_demo(image)
    cloneImage, contours, heriachy  = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i , contour in enumerate(contours):
        cv.drawContours(image, contours, i, (0,0,255), 1)
        print(i)
    cv.imshow("detect contours",image)
print("=====Hello Python=====")
image = cv.imread("opencv_sources/circle.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
contours_demo(image)
cv.waitKey(0)
cv.destroyAllWindows()

24对象测量

  • 弧长与面积:轮廓发现,计算每个轮廓的弧长与面积,像素单位。
  • 多边形拟合:获取轮廓的多边形拟合结果。
  • 几何矩计算:使用几何矩计算对象中心。
import cv2 as cv
import numpy as np

def measure_object(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    print("threshold value:%s"%ret)
    cv.imshow("binary image",binary)
    outImage, contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i, contour in enumerate(contours):
        area = cv.contourArea(contour)
        x,y,w,h = cv.boundingRect(contour)
        mm = cv.moments(contour)  # 几何矩,字典类型
        if mm['m00']:
            cx = mm['m10']/mm['m00']
            cy = mm['m01']/mm['m00']
        else:
            continue
        cv.circle(image, (np.int(cx),np.int(cy)), 3, (0,255,255), -1)
        cv.rectangle(image, (x,y), (x+w,y+h), (0,0,255), 2)
        print("contour area %s"%area)
    cv.imshow("measure-contours", image)


print("=====Hello Python=====")
image = cv.imread("opencv_sources/rect.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
measure_object(image)
cv.waitKey(0)
cv.destroyAllWindows()

多边形拟合
import cv2 as cv
import numpy as np

def measure_object(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    print("threshold value:%s"%ret)
    cv.imshow("binary image",binary)
    dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)
    outImage, contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i, contour in enumerate(contours):
        area = cv.contourArea(contour)
        x,y,w,h = cv.boundingRect(contour)
        # 求宽高比
        rate = min(w, h)/max(w, h)
        print("rectangle rate:%s"%rate)

        mm = cv.moments(contour)  # 几何矩,字典类型
        type(mm)
        if mm['m00']:
            cx = mm['m10']/mm['m00']
            cy = mm['m01']/mm['m00']
        else:
            continue
        cv.circle(dst, (np.int(cx),np.int(cy)), 3, (0,255,255), -1)
        # cv.rectangle(dst, (x,y), (x+w,y+h), (0,0,255), 2)
        print("contour area %s"%area)
        # 多边形逼近
        approxCurve = cv.approxPolyDP(contour, 4 , True)

        if approxCurve.shape[0] == 3:  # 多边形的边数
            cv.drawContours(dst, contours, i, (0,255,0), 2)
    cv.imshow("measure-contours", dst)

print("=====Hello Python=====")
image = cv.imread("opencv_sources/approxi.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
measure_object(image)
cv.waitKey(0)
cv.destroyAllWindows()

25膨胀与腐蚀

膨胀的作用:对象增加一个像素;平滑对象边缘;减少或填充对象之间的距离


import cv2 as cv
def erode_demo(image):
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))
    dst = cv.erode(binary, kernel)
    cv.imshow("erode_demo",dst)

def dilate_demo(image):
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dst = cv.dilate(binary, kernel)
    cv.imshow("dilate_demo",dst)

print("=====Hello Python=====")
image = cv.imread("opencv_sources/rect.png")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",image)
dilate_demo(image)
cv.waitKey(0)
cv.destroyAllWindows()

相关文章

网友评论

      本文标题:2019-06-03 OpenCV学习

      本文链接:https://www.haomeiwen.com/subject/gnphxctx.html