【OpenCV】(霍夫)直线、圆检测

一、直线检测

1.1 概念

  霍夫直线变换:用来做直线检测;前提条件-边缘检测已经完成;平面空间到极坐标空间转换。
                在这里插入图片描述
        在这里插入图片描述
  不知道图像(边缘检测后的图像)中有没有直线,那么就将边缘检测后的图像由平面坐标转到极坐标表示,找到极坐标下亮的点,然后将这些点再反向映射到平米空间就可得到直线。完成霍夫直线检测

1.2 实战

1.2.1 手动cv.HoughLines

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''边缘检测'''
def canny_demo(image):
    # 1.高斯模糊:最后两个参数给定一个就可以自动求取另一个,所以只给其中一个赋值就可以
    blur=cv.GaussianBlur(image,(3,3),0)
    #2.灰度处理
    gray=cv.cvtColor(blur,cv.COLOR_BGR2GRAY)
    #3.求取梯度,也可以不用梯度,直接将灰度图传入cv.canny
    grad_x=cv.Sobel(gray,cv.CV_16SC1,1,0)
    grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
    #4.求边缘
    edge_output=cv.Canny(grad_x,grad_y,50,150)#参数:x梯度,y梯度 ,低阈值,高阈值
    cv.imshow('canny-demo',edge_output)
    return edge_output
'''直线检测'''
def huf_line_detect():
    img = cv.imread(r'D:\Project\Opencv\Learning01\line.jpg')
    edge_output=canny_demo(img)

    lines=cv.HoughLines(edge_output,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))
        # 绘制直线:参数图像,点1,点2,颜色,直线宽度
        cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)
        cv.imshow('img',img)

img = cv.imread(r'D:\Project\Opencv\Learning01\line.jpg')
cv.imshow('origin',img)
huf_line_detect()
cv.waitKey(0)

在这里插入图片描述

1.2.2 调用API(推荐)cv.HoughLinesP

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''边缘检测'''
def canny_demo(image):
    # 1.高斯模糊:最后两个参数给定一个就可以自动求取另一个,所以只给其中一个赋值就可以
    blur=cv.GaussianBlur(image,(3,3),0)
    #2.灰度处理
    gray=cv.cvtColor(blur,cv.COLOR_BGR2GRAY)
    #3.求取梯度,也可以不用梯度,直接将灰度图传入cv.canny
    grad_x=cv.Sobel(gray,cv.CV_16SC1,1,0)
    grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
    #4.求边缘
    edge_output=cv.Canny(grad_x,grad_y,50,150)#参数:x梯度,y梯度 ,低阈值,高阈值
    cv.imshow('canny-demo',edge_output)
    return edge_output
'''直线检测'''
def line_detect_huf():
    img = cv.imread(r'D:\Project\Opencv\Learning01\line.jpg')
    edge_output=canny_demo(img)
    lines=cv.HoughLinesP(edge_output,1,np.pi/180,100,minLineLength=50,maxLineGap=10)
    for line in lines:
        x1,y1,x2,y2=line[0]
        cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)
    cv.imshow('img', img)

img = cv.imread(r'D:\Project\Opencv\Learning01\line.jpg')
cv.imshow('origin',img)
line_detect_huf()
cv.waitKey(0)

在这里插入图片描述

二、圆检测

2.1 概念

  霍夫圆变换原理:从平面坐标到极坐标转换三个参数C(x0,y0,r)其中x0,y0是圆心,。假设平面坐标的任意一个圆上的点,转换到极坐标中C(x0,y0,r)处有最大值,霍夫变换正是利用这个原理。
            在这里插入图片描述
        在这里插入图片描述
  现实考量:
  因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
  基于效率考量,OpenCV中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:1.边缘检测,可能发现圆心;2.基于第一步的基础上从候选圆心开始计算最佳半径大小。

2.2 实战

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

'''圆检测'''
def circle_detect():
    img = cv.imread(r'D:\Project\Opencv\Learning01\monney.jpg')
    #边缘保留滤波
    dst=cv.pyrMeanShiftFiltering(img,10,100)
    gray=cv.cvtColor(dst,cv.COLOR_BGR2GRAY)
    #霍夫圆检测,跟直线检测一样可以不用梯度图
    circles=cv.HoughCircles(gray,cv.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
    circles=np.uint16(np.around(circles))
    for circle in circles[0,:]:
        cv.circle(img,(circle[0],circle[1]),circle[2],(0,0,255),2)
        cv.circle(img, (circle[0], circle[1]), 2, (255, 0, 0), 2)
    cv.imshow('img',img)


img = cv.imread(r'D:\Project\Opencv\Learning01\monney.jpg')
cv.imshow('origin',img)
circle_detect()
cv.waitKey(0)

  出现多余的圆是因为霍夫检测对噪声非常敏感,所以可以使用一些滤波调整,将噪声去除。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值