智能图像分析——Hough变换

article/2025/9/29 6:14:16

一、原理

引用
hough变换利用点、线对偶的思想,把提取图像空间中直线的问题转换成在参数空间/hough空间中计算点的峰值的问题。
在x − y坐标系中,假设有一条直线过点( x0 , y0 ),那么我们可以把这条直线的方程记为

y=mx+b(1)
现在,如果我们把参数和变量的身份对换一下,即(m,b)是变量,(x,y)是参数,那么公式1可以写成
b=−x0m+y0(2)
那么在b − m坐标系中,( x 0 , y 0 ) 就确定了一条直线。 回到x − y 坐标系,对直线y = m x + b ,记原点到它的距离是r,它的正切线与x轴的夹角是θ , θ ∈ [ 0 , 180 ] ,

在这里插入图片描述

那么易得

在这里插入图片描述
,把公式3,4代入公式1,整理可得

在这里插入图片描述

r=xcosθ+ysinθ(5)
由公式5可知,如果是在θ − ρ坐标系中,( x 0 , y 0 ) 就确定了一条正弦曲线。上述的所谓x − y , m − b , θ − ρ 坐标系,我们分别称他们为图像空间、参数空间、hough空间。通过上面的分析可知,图像空间中的任何一个坐标点都对应着参数空间中的一条直线(或者hough空间中的一条正弦曲线),那么很多点就可以在参数空间中对应很多直线,这些直线间会相交,而每一个相交点( m i , b i ) 都代表着在此处相交的若干条直线 对应着的在图像空间中的哪些点应该在同一条直线上,并且这条直线的(斜率,截距)就是(m_i,b_i),此时,我们只需要计算哪些相交点有更多的直线经过,那这些相交点就更有可能是我们想要提取的原图像中的直线。 在实际操作时,我们使用θ , r,因为有些直线的斜率根本不存在或者很大,比并且( θ i , ρ i ) 也能表示图像空间中的一条直线,把公式3,4代入

在这里插入图片描述

二、语法

2.1 enumerate

引用

2.1.1 基本用法

s = [2,5,8,3,6,9]
for i in enumerate(s):print i

结果为:

(0, 2)
(1, 5)
(2, 8)
(3, 3)
(4, 6)
(5, 9)

按照一般的序列迭代方法,可以看出enumerate()函数的返回值是一个元组,元组构成为(index, value),也就是序列索引和值的元组。

2.1.2 第二可选参数,解决索引从0开始输出的问题

enumerate()有两个参数序列和起始索引。
即enumerate(sequence , index)

s = [2,5,8,3,6,9]
for i in enumerate(s, 1):print i

结果为:

(1, 2)
(2, 5)
(3, 8)
(4, 3)
(5, 6)
(6, 9)

2.2 round

引用

2.2.1 round()是python自带的一个函数,用于数字的四舍五入。

2.2.2使用方法(环境python3)

round(number,digits)

参数:
digits>0,四舍五入到指定的小数位
digits=0, 四舍五入到最接近的整数
digits<0 ,在小数点左侧进行四舍五入
如果round()函数只有number这个参数,等同于digits=0

四舍五入规则:

  1. 要求保留位数的后一位<=4,则进位,如round(5.214,2)保留小数点后两位,结果是 5.21
  2. 要求保留位数的后一位“=5”,且该位数后面没有数字,则不进位,如round(5.215,2),结果为5.21
  3. 要求保留位数的后一位“=5”,且该位数后面有数字,则进位,如round(5.2151,2),结果为5.22
  4. 要求保留位数的后一位“>=6”,则进位。如round(5.216,2),结果为5.22

2.3 argpartition

引用
找到最大值

2.4 column_stack

引用

三、代码

3.1 调用opencv库

调用代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图片
img = cv2.imread('D:/house.png')
# 彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
edges = cv2.Canny(gray, 80, 200)
# 显示原始结果cv2.imwrite('edges.png', edges)
cv2.imshow('edge', edges)
# plt.subplot(121)
# plt.imshow(edges)# 执行Hough直线检测
lines = cv2.HoughLines(edges, 1, np.pi/180, 130)  #cv2.HoughLines 的返回参数 line == [\rho ,\Theta ] ,# 其中,第一个参数表示图像原点距离直线的长度,第二个参数表示沿着x轴的角度大小。
lines1 = lines[:, 0, :]
print('lines', lines)
print('lines1', lines1)for rho,  theta in lines1:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))  # 延长直线的长度,保证在整幅图像上绘制直线y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite('line.png', img)
cv2.imshow('line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

通过调整各项参数,边缘检测图和直线检测图如下图所示:
在这里插入图片描述
可以看到检测效果还不错。
通过打印我们发现cv2.HoughLines()函数返回值为弧长和弧度的数组:
在这里插入图片描述

3.2 不调用函数

(一)

在参考了这位博主和这位博主的帖子之后,我将代码改为如下形式(此处先只修改了Hough变换的部分,边缘检测依然采用库函数):

import cv2
import numpy as np# 读取图片
img = cv2.imread('D:/house.png')
# 彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
edges = cv2.Canny(gray, 80, 200)
# 显示原始结果cv2.imwrite('edges.png', edges)
# cv2.imshow('edge', edges)# def Hough(img, origin, delta=1):
def Hough(img):thetas = np.deg2rad(np.arange(0.0, 181.0, 1))row, col = img.shapeprint('row, col =', row, col)rhomax = int(round(np.sqrt(row*row+col*col)))print('rhomax', rhomax)# 因为ρ会存在负值,所以要先右移,后面减去即可A = np.zeros((2*rhomax, len(thetas)), np.int32)for x in range(row):for y in range(col):if img[x, y] > 0:  # 寻找边缘点for i in range(len(thetas)):  # 找出过边缘点的所有直线rho = int(round(x*np.cos(thetas[i])+y*np.sin(thetas[i])))  # round四舍五入至接近的整数,计算弧长rho += rhomaxA[rho, i] += 1  # 统计参数空间中过点的曲线数目# 统计大于阈值的点数m = 0for x in range(len(thetas)):for y in range(rhomax):if A[y, x] >= 80:  # 设置阈值m += 1print('m=', m)rho_list = np.zeros(m, np.int32)  # 存每个点的弧长theta_list = np.zeros(m, np.int32)  # 存每个点的弧度print('rho_list =', rho_list)print('theta_list =', theta_list)for i in range(m):rho_list[i] = rhotheta_list[i] = ilines = [list(t) for t in zip(rho_list, theta_list)]  # 返回弧长和弧度的数组return lineslines = Hough(edges)
print('lines=', lines)# 画线
for rho,  theta in lines:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))  # 延长直线的长度,保证在整幅图像上绘制直线y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite('line.png', img)
cv2.imshow('line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

检测结果如下图所示:
在这里插入图片描述
在这里插入图片描述

由于图片灰度化和边缘检测都是调用的库函数,所以边缘检测图是没有问题的,然而直线检测显然是错的。。。。。。且用自己编写的函数明显运行速度变慢。

(二)

经过对上述程序的分析,我推测可能是在寻找过边缘点直线的过程中,将弧长四舍五入产生了较大的误差,于是对程序做了如下修改:

import cv2
import numpy as np# 读取图片
img = cv2.imread('D:/house.png')
# 彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
edges = cv2.Canny(gray, 80, 200)
# 显示原始结果cv2.imwrite('edges.png', edges)
# cv2.imshow('edge', edges)# def Hough(img, origin, delta=1):
def Hough(img):thetas = np.deg2rad(np.arange(0.0, 181.0, 1))row, col = img.shapeprint('row, col =', row, col)rhomax = int(round(np.sqrt(row*row+col*col)))print('rhomax', rhomax)# 因为ρ会存在负值,所以要先右移,后面减去即可A = np.zeros((2*rhomax, len(thetas)), np.int32)for x in range(row):for y in range(col):if img[x, y] > 0:  # 寻找边缘点for i in range(len(thetas)):  # 找出过边缘点的所有直线rho = int(round((x*np.cos(thetas[i])+y*np.sin(thetas[i])), 1))  # round四舍五入至小数点后1位,计算弧长rho += rhomaxA[rho, i] += 1  # 统计参数空间中过点的曲线数目# 将弧长误差为1的点近似为同一个点for x in range(len(thetas)):for y in range(rhomax):for i in range(rhomax-y):if abs(A[y, x]-A[y+i, x]) <= 1:  # 设置阈值,小于等于1判为同一个点A[y + i, x] = A[y, x]# 统计大于阈值的点数m = 0for x in range(len(thetas)):for y in range(rhomax):if A[y, x] >= 80:  # 设置阈值m += 1print('m=', m)rho_list = np.zeros(m, np.int32)  # 存每个点的弧长theta_list = np.zeros(m, np.int32)  # 存每个点的弧度print('rho_list =', rho_list)print('theta_list =', theta_list)for i in range(m):rho_list[i] = rhotheta_list[i] = ilines = [list(t) for t in zip(rho_list, theta_list)]  # 返回弧长和弧度的数组return lineslines = Hough(edges)
print('lines=', lines)# 画线
for rho,  theta in lines:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))  # 延长直线的长度,保证在整幅图像上绘制直线y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite('line.png', img)
cv2.imshow('line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行速度又慢了许多。。。。。。检测结果如下:
在这里插入图片描述
显然没有任何改进。
此时我发现输出lines如下:
在这里插入图片描述
与直接调用函数返回的值大相径庭,根本就是错的。。。。。。

(三)

分析发现是rho_list和theta_list赋值赋错了,然后将程序改为如下形式:

    i = 0for x in range(len(thetas)):for y in range(rhomax):if A[y, x] >= delta:  # 设置阈值rho_list[i] = y-rhomaxtheta_list[i] = thetas[x]i += 1print('rho_list =', rho_list)print('theta_list =', theta_list)lines = [list(t) for t in zip(rho_list, theta_list)]  # 返回弧长和弧度的数组

输出值如下图所示:
在这里插入图片描述
检测结果如是:
在这里插入图片描述
还是错的。
由于调用的canny算子阈值没有变,都是80,200,输入边缘图是一样的,我将Hough变换的阈值也变为和调用的函数一样的值130,然后发现大于阈值的只有三条线,原本应该有七条线,且这三条线都是错的。判断边缘点这一步应该不会出错,那么就是说在存入Hough空间数组A这一步就出错了。

(四)

实在写不出来,去翻了一下原函数。请见这位博主和这位博主的帖子以及他们的评论区。非常感谢大家的分享。
我仿照原函数写了一个代码如下:

import cv2
import numpy as np# 读取图片
img = cv2.imread('D:/house.png')
# 彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
edges = cv2.Canny(gray, 80, 200)
# 显示原始结果cv2.imwrite('edges.png', edges)
# cv2.imshow('edge', edges)# def Hough(img, origin, delta=1):
def Hough(img, delta = 130):row, col = img.shape  # 获取图片长宽rho = 1.0  #定义以像素为单位的距离精度为1  float型theta = 1*np.pi/180  #定义以弧度为单位的角度精度为1  float型print('rho=', rho)print('theta=', theta)# 由角度和距离的分辨率得到角度和距离的数量,即霍夫变换后角度和距离的个数numangle = round(np.pi / theta)numrho = int(((row + col) * 2 + 1) / rho)# thetas = np.deg2rad(np.arange(0.0, 180.0, theta))  # 弧度数组# 定义累加器即霍夫空间,它是用一维数组表示二维空间A = np.zeros(((numrho + 2), (numangle + 2)), np.int32)  # int型数组# 做好tabSin、tabCos数组angle = 0.0tabSin = np.zeros(numangle, np.float)tabCos = np.zeros(numangle, np.float)for n in range(numangle):tabSin[n] = float(np.sin((angle)/rho))tabCos[n] = float(np.cos((angle)/rho))angle += theta# 逐点Hough变换,将结果存入累加器数组内for x in range(row):for y in range(col):if img[x, y] > 0:  # 寻找边缘点for i in range(numangle):r = int(round(x * tabCos[i] + y * tabSin[i]))  # round四舍五入至接近的整数,r表示距离r = int(r+(numrho - 1) / 2)A[r+1, i+1] += 1  # 在累加器内找到它们所对应的位置(即霍夫空间内的位置),其值加1# 找到局部极大值,即非极大值抑制, 记录个数m = 0rho_list = np.zeros(numrho, np.float)  # 存每个点的弧长theta_list = np.zeros(numangle, np.float)for x in range(numrho):for y in range(numangle):if A[x+1, y+1] >= delta:  # 设置阈值if A[x+1, y+1] > A[x+1, y] and A[x+1, y+1] >= A[x+1, y+2] and A[x+1, y+1] > A[x, y+1] and A[x+1, y+1] >= A[x+2, y+1]:  # 在四邻域内进行非极大值抑制rho_list[m] = (x - (numrho - 1) / 2) * rhotheta_list[m] = y * thetam += 1print('rho_list =', rho_list)print('theta_list =', theta_list)rho_list = rho_list[rho_list != 0]theta_list = theta_list[theta_list != 0]print('rho_list =', rho_list)print('theta_list =', theta_list)lines = [list(t) for t in zip(rho_list, theta_list)]  # 返回弧长和弧度的数组return lineslines = Hough(edges)
print('lines=', lines)# 画线
for rho,  theta in lines:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))  # 延长直线的长度,保证在整幅图像上绘制直线y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite('line.png', img)
cv2.imshow('line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

检测结果如下图所示:
在这里插入图片描述
这回总算是检测出了八个点,比之前的三个点好一些,但还是不对。
在这里插入图片描述
通过与运行原函数的结果相比对,发现弧长差不多能对上,但是角度对不上,也就是说还是公式的计算出了问题。

(五)

重新分析一遍代码思路:

  1. 构建Hough空间
    (1)首先获取图片宽度和高度。
    (2)定义距离精度和角度精度。在这里我定义的都是1,距离精度是1个像素,角度精度是1°,换成弧度也就是代码中表示的那样.
    (3)定义角度的个数和距离的个数。这里角度的个数没有异议,肯定是180个。至于的个数,个人认为不用纠结为什么是(周长+1)/距离精度,前面提到的博主在帖子和评论区讲的都比较清楚,距离长度最小值肯定是图片对角线距离的最大值,只要构建的数组空间存放距离的那一栏大于对角线长度就可以,周长显然大于对角线长度,所以是可以的,而+1是为了防止“0”效应,这里到了后面Hough变换那一步就会明白。当然如果用弧度最小值来构建空间我认为也是没有任何问题的。
    (4)最后是构建sin和cos数组。
  2. 进行Hough变换
    (1)遍历边缘图,找出所有边缘点。
    (2)画出所有过边缘点的直线,判断原点到每一条直线的距离,将距离和角度存入Hough空间相应位置。问题就出在这里。这里row是指图片的高,col是指图片的宽,我的所有循环中x都是取的row(高)的范围,y取得是col(宽)的范围,也就是说我这里的横轴其实是y,纵轴是x,因此我的距离公式应该是:
r=y*cos+x*sin

而不是:

r=x*cos+y*sin

将这里改了之后就对了。。。。。。
继续记录一下我的心路历程。
在图像中每个像素代表的是一个小方格,然而我们在计算距离的时候应该是把每个小方格看成了一个像素点的。如下图所示:
在这里插入图片描述
举个例子。假设图中阴影部分为边缘点像素格。最开始我把它看成一个格子,那么我理所当然的将原点距离它的长度想成了原点与①的距离,这个格子的坐标为(3,2),但它是横着的第四个格子,竖着的第三个格子,由勾股定理显然r应该是5,即应该是:

r=np.sqrt((x+1)**2+(y+1)**2)

但如果是这样的话,那么假如(0,0)这个点是边缘点的话,它的距离显然不为0。但实际上这个点就是原点,它离原点的距离应该就是0。所以我们应该计算的是原点离②的距离。所以公式中出现的是:

r = y * tabCos[i] + x * tabSin[i]

而不是:

r = (y+1) * tabCos[i] + (x+1) * tabSin[i]

因为计算出的r可能为负值,所以我们要再加距离偏移的一半即1024,使r的值最后都能落在[0,2048]这个区间。
然后我们将这组距离、角度存入Hough数组。还是以刚才的例子为例,在存入的过程中,假设距离为5,角度为37°,那么我们应该在(6,38)这个格子+1,这是为了将hough空间的边缘空出来,方便我们进行下一步的非极大值抑制。

  1. 进行非极大值抑制
    (1)这里我们采用的是四邻域比较法。遍历Hough空间除边缘外的每一个点。这里我们表示Hough空间的数组A的范围是横轴[0 ~ 181]共182个格子,纵轴[0 ~ 2050]共2051个格子,我们需要比较y=[1 ~ 180],x=[1 ~ 2049]这些个格子,如图阴影部分所示:
    在这里插入图片描述
    每个格子与它上下左右的四个格子相比较。
    (2)找到最大值后我们就存入新的距离、弧度数组,并将其作为返回值进行下一步的画线。
    最后放一下代码:
import cv2
import numpy as np# 读取图片
img = cv2.imread('D:/house.png')
# 彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
edges = cv2.Canny(gray, 80, 200)
# 显示原始结果cv2.imwrite('edges.png', edges)
# cv2.imshow('edge', edges)# def Hough(img, origin, delta=1):
def Hough(img, delta = 130):row, col = img.shape  # 获取图片长宽rho = 1.0  #定义以像素为单位的距离精度为1  float型theta = 1*np.pi/180  #定义以弧度为单位的角度精度为1  float型print('rho=', rho)print('theta=', theta)# 由角度和距离的分辨率得到角度和距离的数量,即霍夫变换后角度和距离的个数numangle = round(np.pi / theta)numrho = int(((row + col) * 2 + 1) / rho)# thetas = np.deg2rad(np.arange(0.0, 180.0, theta))  # 弧度数组# 定义累加器即霍夫空间,它是用一维数组表示二维空间A = np.zeros(((numrho + 2), (numangle + 2)), np.int32)  # int型数组# 做好tabSin、tabCos数组angle = 0.0tabSin = np.zeros(numangle, np.float)tabCos = np.zeros(numangle, np.float)for n in range(numangle):tabSin[n] = float(np.sin((angle)/rho))tabCos[n] = float(np.cos((angle)/rho))angle += theta# 逐点Hough变换,将结果存入累加器数组内for x in range(row):for y in range(col):if img[x, y] > 0:  # 寻找边缘点for i in range(numangle):r = int(round(y * tabCos[i] + x * tabSin[i]))  # round四舍五入至小数点后1位,r表示距离r += int((numrho - 1) / 2)A[r+1, i+1] += 1  # 在累加器内找到它们所对应的位置(即霍夫空间内的位置),其值加1,实际距离r就是r# 找到局部极大值,即非极大值抑制, 记录个数m = 0rho_list = np.zeros(numrho, np.float)  # 存每个点的弧长theta_list = np.zeros(numangle, np.float)for x in range(numrho):  # 0~2048for y in range(numangle):  # 0~179if A[x+1, y+1] >= delta:  # 设置阈值  x+1=[1,2049], y+1=[1,180]if A[x+1, y+1] > A[x+1, y] and A[x+1, y+1] >= A[x+1, y+2] and A[x+1, y+1] > A[x, y+1] and A[x+1, y+1] >= A[x+2, y+1]:  # 在四邻域内进行非极大值抑制rho_list[m] = (x - (numrho - 1) / 2) * rhotheta_list[m] = y * thetam += 1print('m=', m)rho_list = rho_list[rho_list != 0]theta_list = theta_list[theta_list != 0]print('rho_list =', rho_list)print('theta_list =', theta_list)lines = [list(t) for t in zip(rho_list, theta_list)]  # 返回弧长和弧度的数组return lineslines = Hough(edges)
print('lines=', lines)# 画线
for rho,  theta in lines:a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))  # 延长直线的长度,保证在整幅图像上绘制直线y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite('line.png', img)
cv2.imshow('line', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

检测结果如图所示:
在这里插入图片描述
在这里插入图片描述

(六)

将图片灰度化以及canny等所有程序都换成自己编写的之后,程序运行很慢,效果如下图所示:
在这里插入图片描述
通过更改阈值能得到不同的检测效果。

四、错误

在调试代码的过程中,遇到了许多问题,在这里记录一下。

(一)、数据类型与数组类型不匹配

这个问题出现了许多次,错误如下:

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

分析发现应该是说数组的索引必须是整数,不能是浮点数、字符串等其他类型。
分步运行时发现r是一个浮点数,如下图所示:
在这里插入图片描述
但我的程序是这样写的:

r = int(round(x * tabCos[i] + y * tabSin[i]))  # round四舍五入至小数点后1位,r表示距离
r += (numrho - 1) / 2

然后我发现第二行的

r += (numrho - 1) / 2

输出为浮点数。但是如果改成如下形式输出就为整数:

r += (numrho - 1) * 2

也就是除法的结果会变成一个浮点数。所以我将第二行也进行了一个int转换:

r = int(round(x * tabCos[i] + y * tabSin[i]))  # round四舍五入至接近的整数,r表示距离r = int(r+(numrho - 1) / 2)

这回总算是对了。

(二)opencv中的cvRound与c++中的round

c++中的round为四舍五入,而opencv中的cvRound为五舍六入。请见这位博主的帖子。
此处应该不用在意这些微小的差别。


http://chatgpt.dhexx.cn/article/60YZq1yn.shtml

相关文章

霍夫Hough变换

参考: https://blog.csdn.net/qq_15971883/article/details/80583364 MATLAB帮助文档 Hough变换是一种使用表决方式的参数估计技术,其原理是利用图像空间和Hough参数空间的线-点对偶性,把图像空间中的检测问题转换到参数空间中进行。 利用Hough变换检测直线 记住:直角坐标…

Hough变换及MATLAB示例

前言 在车道线检测中&#xff0c;最小二乘法&#xff0c;Hough变换是车道线模型拟合的传统方法之一&#xff0c;通过一系列离散的点拟合出车道直线&#xff0c;也就是得到基于像素平面坐标系的左车道和右车道直线方程。 Hough变换 Hough变换的基本思想 我们先来看看如何表达…

hough变换算法

VoteNet网络中会用Deep Hough Voting&#xff0c;所以先来学习一下Hough Voting。 正文开始 hough变换算法 1、算法思想 霍夫变换于1962年由Paul Hough 首次提出&#xff0c;后于1972年由Richard Duda和Peter Hart推广使用&#xff0c;经典霍夫变换用来检测图像中的直线&…

Hough 变换

Hough 变换是图像处理中&#xff0c;检测直线最基本&#xff0c;也是应用最广泛的一种传统方法。虽然现在是深度学习大行其道的时代&#xff0c;但是很多传统的算法&#xff0c;依然有其参考的价值所在&#xff0c;至少从数学表达上来看&#xff0c;是更加的简洁&#xff0c;有…

Hough transform(霍夫变换)

主要内容&#xff1a; 1、Hough变换的算法思想 2、直线检测 3、圆、椭圆检测 4、程序实现 一、Hough变换简介 Hough变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换的基本原理在于利用点与线的对偶性&#xff0c;将原始图像空间的给定的曲线通过曲线表达形式变…

Hough变换

目录 一、Hough变换简介 二、Hough变换的数学理解 1.x-y变量空间至k-b参数空间的变换 2.x-y变量空间至-空间的变换 三、Hough变换应用于线检测&#xff08;MATLAB实现&#xff09; 1.检测步骤 2.使用MATLAB工具箱中的Hough变换函数进行边缘检测 一、Hough变换简介 霍夫变…

图像处理:Hough变换原理分析

目录 一、前言 二、直线函数的形式化表示 2.1 直线被方程表示 2.2 直线被图表表示 2.3 直线的表格表示 三、hough变换的提出 3.1 极坐标表示点和线 四、 hough变换的原理 4.1 极坐标的​编辑表格 4.2 用​编辑平面表示&#xff1a;过任意点P(x,y)做所有射线&#xff0…

Hough变换原理-直线检测

目录 一、简介 二、原理 三、Python代码实现 一、简介 Hough&#xff08;霍夫&#xff09;变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换是将图像坐标空间变换到参数空间&#xff0c;利用点与线的对偶性&#xff0c;将原始图像空间的给定的曲线&#xff08…

YUV444、YUV422、YUV420、YUV420P、YUV420SP、YV12、YU12、NV12、NV21

前言 各种YUV格式多如牛毛啊&#xff0c;刚开始学起来确实很费劲&#xff0c;网上搜索的文章讲的并不是很明白。 各种不同的YUV格式其实只是采样方式和存储方式不同&#xff0c;就这两点&#xff0c;不同的采样方式是为了实现节省内存&#xff0c;不同的存储方式暂时不了解有…

2023-02-24:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420SP格式文件,采用YUV420P转YUV420SP的方式。

2023-02-24&#xff1a;请用go语言调用ffmpeg&#xff0c;解码mp4文件并保存为YUV420SP格式文件&#xff0c;采用YUV420P转YUV420SP的方式。 答案2023-02-24&#xff1a; 使用 github.com/moonfdd/ffmpeg-go 库。 解码后就是yuv420p&#xff0c;然后用SwsScale函数转换成yuv…

ffmpeg处理YUV422和YUV420P相互转换

YUV422空间大小计算 YUV422封包width*heightwidth/2*height*2YUYV Y分量width*heightYUYV U分量width/2*heightYUYV V分量width/2*height YUV420空间大小计算 YUV420封包width*heightwidth/2*height/2*2Y分量width*heightU分量width/2*height/2V分量width/2*height/2 extern &…

Android Camera2 YUV420_888 格式详解

Camera2 YUV420_888 官网文档介绍 Android PAI 对 YUV420_888的介绍 &#xff0c;大致意思如下&#xff1a; 它是YCbCr的泛化格式&#xff0c;能够表示任何4:2:0的平面和半平面格式&#xff0c;每个分量用8 bits 表示。带有这种格式的图像使用3个独立的Buffer表示&#xff0c;每…

【音视频数据数据处理 2】【YUV篇】将YUV420P_I420数据旋转90°-180°-270°-镜像旋转

【音视频数据数据处理 2】【YUV篇】将YUV420P_I420数据旋转90 一、理论分析&#xff08;以yuv420p_i420格式为例&#xff09;二、顺时针旋转90 代码实现三、顺时针旋转180 代码实现四、旋转90-180-270-镜像旋转&#xff0c;完整代码实现五、运行结果 本文接着前文&#xff1a; …

YUV420->RGB888格式转换的CPP实现

git地址&#xff1a; GitHub - Evayangelion/EYUVConverter: A YUV converter implemented by cpp 上一次学习了YUV各种采样和存储方式的区别&#xff08;YUV知识存档&#xff09; 接下来一起学习一下RGB格式的知识和YUV到RGB的转换方式 RGB色彩模式的分类 RGB的分类相较YUV来说…

YUV444,YUV420P,YUV420SP,YUV422P,YUV422SP,NV12,NV21,NV16,NV61等格式区分与存储简介

一、基础知识&#xff1a; 概述 YUV是顏色編碼方式&#xff0c;常用於視頻及圖像處理中。 其中的YUV是三個分量。“Y”表示明亮度&#xff08;Luminance或Luma&#xff09;&#xff0c;也就是灰度值。“U”和“V” 表示的是彩色信息&#xff0c;分別爲色度和濃度&#xff08;C…

OpenGL渲染YUV420P

一 、YUV420P数据格式二 、GLFW渲染YUV420P2.1 定义顶点数据2.2 创建YUV三张纹理2.3上行YUV420数据2.4 渲染纹理2.5 着色器 三、代码地址以及存在的问题四 、解决存在的问题 一 、YUV420P数据格式 图片来源于谷歌 结合上图可以看出YUV420P的特点如下&#xff1a; ①无论在横向还…

详解 YUV 格式(I420/YUV420/NV12/NV12/YUV422)

转载自&#xff1a;划水型派大星 YUV &#xff08;YCbCr&#xff09;是一种像素格式&#xff0c;常见于视频编码与静态图像。与 RGB 格式&#xff08;红-绿-蓝&#xff09;相反&#xff0c;YUV 分别由一个称为 Y&#xff08;相当于灰度&#xff09;的“亮度”分量&#xff08;…

ffmpeg学习笔记(2)-YUV420算法原理

ffmpeg学习笔记(2)——YUV420算法原理 一、YUV像素格式 YUV的组成格式如下图所示 Y:明亮度&#xff0c;即灰度值 U、V&#xff1a;颜色 YUV格式将亮度信息和色彩信息分离&#xff0c;没有色彩信息依然能够显示图像&#xff08;没有色彩信息&#xff09;&#xff0c;很好的解…

音视频编解码: YUV存储格式中的YUV420P,YUV420SP,NV12, NV21理解(转)

概述 之前介绍了YUV码流的采样格式&#xff0c;下面分析下YUV码流的存储格式&#xff0c;YUV码流的存储格式与采样格式息息相关。总的来讲&#xff0c;YUV存储格式主要分为两种&#xff1a; planar 平面格式 指先连续存储所有像素点的 Y 分量&#xff0c;然后存储 U 分量&…

图像编码YUV420格式

目录 一、YUV简介 二、RGB 到 YUV 的转换 三、YUV采样 YUV 4:4:4 YUV 4:2:2 YUV 4:2:0 四、YUV 存储格式 基于 YUV 4:2:2 采样的格式 YUYV 格式 UYVY 格式 YUV 422P 格式 基于 YUV 4:2:0 采样的格式 YU12 和 YV12 格式 NV12 和 NV21 格式 一、YUV简介 YUV&#x…