2019-06-03 OpenCV学习

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()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容