python-opencv学习笔记(五):霍夫变换

霍夫变换原理

霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。Hough变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换的基本原理在于利用点与线的对偶性,将原始图像空间的给定的曲线通过曲线表达形式变为参数空间的一个点。这样就把原始图像中给定曲线的检测问题转化为寻找参数空间中的峰值问题。也即把检测整体特性转化为检测局部特性。比如直线、椭圆、圆、弧线等。

说起直线,我们会想到笛卡尔坐标系(即x-y坐标系)下的直线方程,细分之则有点斜式、截距式等, y = k x + b y=kx+b y=kx+b 是我们最熟悉的一种,但直线垂直于x轴时斜率 k k k不存在,这给我们带来许多不便之处。

这时笛卡尔坐标系就能转换为极坐标系: p = x c o s θ + y s i n θ p=xcos\theta + y sin\theta p=xcosθ+ysinθ,变形可得:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上图,假定在一个88的平面像素中有一条直线,并且从左上角(1,8)像素点开始分别计算θ为0°、45°、90°、135°、180°时的ρ,图中可以看出ρ分别为1、(9√2)/2、8、(7√2)/2、-1,并给这5个值分别记一票,同理计算像素点(3,6)点θ为0°、45°、90°、135°、180°时的ρ,再给计算出来的5个ρ值分别记一票,此时就会发现ρ = (9√2)/2的这个值已经记了两票了,以此类推,遍历完整个88的像素空间的时候ρ = (9√2)/2就记了5票, 别的ρ值的票数均小于5票,所以得到该直线在这个88的像素坐标中的极坐标方程为 (9√2)/2=xCos45°+y*Sin45°,到此该直线方程就求出来了。(PS:但实际中θ的取值不会跨度这么大,一般是PI/180)。

上述图文说明引用自Opencv学习笔记-----霍夫变换直线检测及原理理解

关于霍夫变换还有其它资料,可以看最后的参考与推荐。这里我就不再介绍了,我们直接来看opencv的代码。

cv2.HoughCircles

import cv2
import numpy as np


planets = cv2.imread('640.jpg')
gray_img = cv2.cvtColor(planets,cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)


circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
# circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, cimg.shape[0]/64, param1=p1, param2=p2, minRadius=25, maxRadius=0)

circles = np.uint16(np.around(circles))

for i in circles[0,:]:
    #画出外圆
    cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),6)
    # 画出圆心
    cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow("HoughCirlces",planets)
cv2.imwrite("HoughCirlces.jpg",planets)
cv2.waitKey()
cv2.destroyAllWindows()

上面程序运行后可以得到下方的图像,上一半为原图。

在这里插入图片描述

其中关于cv2.HoughCircles参数解析为:

  1. 第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
  2. 第二个参数,InputArray类型的lines,检测方法. 目前, 唯一被实现的方法是#HOUGH_GRADIENT
  3. 第三个参数,以像素为单位的距离精度。另一种形容方式是图像分辨率与累加器分辨率之比dp
  4. 第四个参数,直线搜索时的进步尺寸的单位minDist。被检测到的圆心的最小距离. 如果该参数很小, 除了一个正确的圆之外, 该圆的邻居也可能被错误地检测出来. 如果该参数很大, 一些圆将可能被错过
  5. 第五个参数,int类型的param1,第一个指定方法参数的参数. 在#HOUGH_GRADIENT的情况下,其为传递给Canny边缘检测的两个阈值中较高的阈值(较小的阈值为1/2)
  6. 第六个参数,param2有默认值0。在#HOUGH_GRADIENT的情况下, 它是检测阶段圆心的累加器阈值该值越小, 越多错误的圆将被检测出来. 在投票中获得高票的圆将被先返回.
  7. 第七个和第八个参数分别为最小圆圈半径和最大圆圈半径,如果maxRadius圆圈半径为0,那么将是最大的圆半径;如果小于0,则返回圆心位置。

而其中的circles:

  • circles[0][0]将返回x坐标;
  • circles[0][1]将返回y坐标;
  • circles[0][2]返回半径。

实例

霍夫圆变换可以根据需求自动调整:

import cv2
import numpy as np
import sys

def onTrackbarChange(max_slider):
    cimg = np.copy(img)

    p1 = max_slider
    p2 = max_slider * 0.4

    # Detect circles using HoughCircles transform
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, cimg.shape[0]/64, param1=p1, param2=p2, minRadius=25, maxRadius=50)

    # If at least 1 circle is detected
    if circles is not None:
        cir_len = circles.shape[1] # store length of circles found
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            # Draw the outer circle
            cv2.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
            # Draw the center of the circle
            cv2.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
    else:
        cir_len = 0 # no circles detected
    
    # Display output image
    cv2.imshow('Image', cimg)    

    # Edge image for debugging
    edges = cv2.Canny(gray, p1, p2)
    cv2.imshow('Edges', edges)

    

    
if __name__ == "__main__":
    # Read image
    img = cv2.imread(r"brown-eyes.jpg", 1)

    # Convert to gray-scale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Create display windows
    cv2.namedWindow("Edges")
    cv2.namedWindow("Image")
    

    # Trackbar will be used for changing threshold for edge 
    initThresh = 105 
    maxThresh = 200 

    # Create trackbar
    cv2.createTrackbar("Threshold", "Image", initThresh, maxThresh, onTrackbarChange)
    onTrackbarChange(initThresh)
    
    while True:
        key = cv2.waitKey(1)
        if key == 27:
            break

    cv2.destroyAllWindows()

在这里插入图片描述
同样,还有线变换:

import cv2
import numpy as np
import sys

def onTrackbarChange(max_slider):
	global img
	global dst
	global gray

	dst = np.copy(img)

	th1 = max_slider 
	th2 = th1 * 0.4
	edges = cv2.Canny(img, th1, th2)
	
	# Apply probabilistic hough line transform
	lines = cv2.HoughLinesP(edges, 2, np.pi/180.0, 50, minLineLength=10, maxLineGap=100)

	# Draw lines on the detected points
	for line in lines:
		x1, y1, x2, y2 = line[0]
		cv2.line(dst, (x1, y1), (x2, y2), (0,0,255), 1)

	cv2.imshow("Result Image", dst)	
	cv2.imshow("Edges",edges)

if __name__ == "__main__":
	
	# Read image
	img = cv2.imread('lanes.jpg')
	
	# Create a copy for later usage
	dst = np.copy(img)

	# Convert image to gray
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

	# Create display windows
	cv2.namedWindow("Edges")
	cv2.namedWindow("Result Image")
	  

	# Initialize threshold value
	initThresh = 500

	# Maximum threshold value
	maxThresh = 1000

	cv2.createTrackbar("threshold", "Result Image", initThresh, maxThresh, onTrackbarChange)
	onTrackbarChange(initThresh)

	while True:
		key = cv2.waitKey(1)
		if key == 27:
			break

	cv2.destroyAllWindows()

在这里插入图片描述

参考与推荐:

[1]. 经典霍夫变换(Hough Transform)

[2]. Opencv学习笔记-----霍夫变换直线检测及原理理解

[3]. 【OpenCV学习笔记】之霍夫变换(Hough Transform)

[4]. 霍夫变换检测直线的公式推导以及基于opencv的源代码分析并实例实现

### 回答1: 错误:无法找到满足要求的版本 python-opencv(来自版本:none)错误:找不到匹配的发行版 python-opencv。 这个错误提示意味着您尝试安装名为 python-opencv 的软件包,但找不到与您的 Python 版本兼容的版本。建议您检查您的 Python 版本和软件包的兼容性,并尝试使用其他版本或其他软件包。 ### 回答2: 这是一个pip安装报错,意思是pyhton-opencv这个库的版本不符合要求,或者是没有符合要求的版本可用。就像购物时去商店里找某个商品,如果这家店没有你想要的品牌或者款式,你就无法购买了一样。 出现这种情况,我们需要检查一下是否输入了正确的库名称和版本号,或者更改一下版本号看看是否能够找到匹配的版本。如果还是无法找到匹配的版本,就需要考虑是不是依赖关系的问题,例如python-opencv这个库需要依赖另一个库,可能是这个依赖库的版本不满足所需要求,导致无法安装。 针对这种情况,我们可以尝试升级pip、减少依赖库的版本或者手动下载安装所需的库。如果实在无法解决,还可以到对应的官方网站或者开源社区寻求帮助,寻找问题的解决方案。 在解决此类问题时,我们应该在提高解决问题能力的同时,也要通过良好的代码编写规范和注释规范来减少问题的发生概率,提高代码的可维护性和可读性。 ### 回答3: 这个错误提示表示当前的Python环境无法找到满足要求的opencv库的安装版本。这可能是由于版本不匹配或者缺少依赖库等原因造成的。 解决这个问题需要考虑以下几个方面: 1. 确认Python版本是否与opencv库要求的Python版本匹配。 首先要查看系统安装的Python版本是否符合opencv库的要求,通常opencv库要求Python版本为2.7或3.5以上。如果当前Python版本过低,可以考虑升级Python版本,或者安装相应版本的opencv库。 2. 确认是否安装了opencv库的依赖库。 opencv库有一些依赖库,例如numpy、matplotlib等,如果这些依赖库没有安装或者版本不匹配,也会导致安装失败。可以通过pip命令安装这些依赖库,例如: pip install numpy matplotlib 3. 尝试使用其他方式安装opencv库。 如果以上方法都没有解决问题,可以考虑尝试其他方式安装opencv库,例如使用源码安装、使用conda安装等。具体方法可以参考相关教程或者官方文档。 总之,解决这个问题需要综合考虑多方面的因素,包括Python版本、依赖库、安装方式等。如果遇到问题可以查看相关错误提示,并参考相关资料进行排查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

submarineas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值