鉴于基础知识掌握的太差,特此开贴,以分类为题目,每天更新一条学习记录。监督自己,好好学习相关理论知识。
1、【2019年11月6日】霍夫变换
常见的有霍夫直线检测与霍夫圆检测。霍夫变换运用两个坐标空间(直角坐标系与参数空间)之间的变换,将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。
Hough直线检测的基本原理在于利用点与线的对偶性,在我们的直线检测任务中,即图像空间中的直线与参数空间中的点是一一对应的,参数空间中的直线与图像空间中的点也是一一对应的。这意味着我们可以得出两个非常有用的结论:
1)图像空间中的每条直线在参数空间中都对应着单独一个点来表示;
2)图像空间中的直线上任何一部分线段在参数空间对应的是同一个点。
因此Hough直线检测算法就是把在图像空间中的直线检测问题转换到参数空间中对点的检测问题,通过在参数空间里寻找峰值来完成直线检测任务。
【参考资料】
https://blog.csdn.net/leonardohaig/article/details/87907462
2、【2019年11月13日】大津法(OTSU,又称最大类间方差法)
图像的二值化,常常用于区分前景与背景差异较大的图像,一般来说,大于某一个阈值可以作为前景,小于则为背景。但是因为图像不同,阈值的设置自然也是问题。于是OTSU出现了,它主要根据前景与背景之间最大的类间方差作为依据,能够自适应返回最大方差处的阈值,极大的方便了二值化图像。其算法过程如下所示:
【公式】 记 M = 256 (单通道灰度分级), Sum = 像素总数
- 背景像素占比
- 前景像素占比
- 背景的平均灰度值
- 前景的平均灰度值
- 0~M灰度区间的灰度累计值
- 类间方差:
- 将公式3、4、5带入公式6可得最终简化公式:
Python代码示例:
def otsu_threshold(im):
width, height = im.size
pixel_counts = np.zeros(256)
for x in range(width):
for y in range(height):
pixel = im.getpixel((x, y))
pixel_counts[pixel] = pixel_counts[pixel] + 1
# 得到图片的以0-255索引的像素值个数列表
s_max = (0, -10)
for threshold in range(256):
# 遍历所有阈值,根据公式挑选出最好的
# 更新
w_0 = sum(pixel_counts[:threshold]) # 得到阈值以下像素个数
w_1 = sum(pixel_counts[threshold:]) # 得到阈值以上像素个数
# 得到阈值下所有像素的平均灰度
u_0 = sum([i * pixel_counts[i] for i in range(0, threshold)]) / w_0 if w_0 > 0 else 0
# 得到阈值上所有像素的平均灰度
u_1 = sum([i * pixel_counts[i] for i in range(threshold, 256)]) / w_1 if w_1 > 0 else 0
# 总平均灰度
u = w_0 * u_0 + w_1 * u_1
# 类间方差
g = w_0 * (u_0 - u) * (u_0 - u) + w_1 * (u_1 - u) * (u_1 - u)
# 类间方差等价公式
# g = w_0 * w_1 * (u_0 * u_1) * (u_0 * u_1)
# 取最大的
if g > s_max[1]:
s_max = (threshold, g)
return s_max[0]
【参考资料】