相机噪声评估

当拥有一个相机,并且写了一个降噪的算法,想要测试降噪的应用效果。

相机在光线不足的情况下产生噪点的原因主要与以下几个因素有关:

感光元件的工作原理:相机的图像传感器是由数百万甚至数千万的感光元件(如CMOS或CCD中的像素)组成的。每一个感光元件都试图捕获进入相机的光。但是,光子的到达是随机的,当光线很弱时,这种随机性更为明显,导致不同感光元件记录的光子数存在较大的差异,从而引发噪点。

ISO的增加:为了在光线不足的环境中获得更亮的图像,相机会增加其ISO值,这实际上是增加了图像传感器的增益。但增加增益的同时,传感器的噪声也会增加,导致图像中出现更多的噪点。

热噪声:当相机工作时,传感器会产生热量。特别是在长时间曝光或高ISO值的情况下,这种热量会增加。传感器的温度越高,产生的热噪声就越明显,这也会在图像中引入噪点。

电路噪声:除了热噪声外,相机内部的电路(如模拟数字转换器)也会引入一定的噪声,特别是在低光照条件下。

信号与噪声比(SNR):在光线充足的环境中,感光元件接收到的光子数(信号)相对于噪声来说是较大的,因此SNR较高,图像质量较好。但在光线不足的环境中,感光元件接收到的光子数减少,而噪声并不显著减少,导致SNR降低,噪点变得更为明显。

无所谓因素,反正有噪声了。

测试设计

目测法:光线充足时肉眼很难发现噪声,而光线比较暗是噪声明显,得出相机光线差时工作效果不理想的结论。

量化噪声:

使用相机拍摄一块纯色色卡,观察噪声情况。

期望:

相机拍出的画面数值保持一致表明没有噪声。(纯黑看不见除外)

相机拍出的画面数值与画面均值比较有一些波动表明有噪声存在。

量化波动情况即量化噪声情况。

色卡

由于色卡不是纯色,所以需要通过一些操作找到纯色部分进行裁剪,再进行评估噪声。

代码使用ipynb 来测试。

裁剪代码:

复制代码
# 导入一些不知道干什么的依赖库

import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

import cv2
import numpy as np
import matplotlib.pyplot as plt


# 输入图像路径
path1 = input("Enter path to the first image: ")
path2 = input("Enter path to the second image: ")

# 打开图片
image1 = cv2.imread(path1)
image2 = cv2.imread(path2)

image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2_gray = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

# 使用 matplotlib 展示结果
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(cv2.cvtColor(image1_gray, cv2.COLOR_BGR2RGB))
ax[0].set_title("image1 gray")
ax[0].axis('off')
ax[1].imshow(cv2.cvtColor(image2_gray, cv2.COLOR_BGR2RGB))
ax[1].set_title("image2 gray")
ax[1].axis('off')
plt.show()

边缘检测,找到最大的色块边界,边缘不连贯就加点滤波

复制代码
# 使用 Canny 边缘检测
blurred = cv2.GaussianBlur(image1_gray, (5, 5), 0)
image1_edged = cv2.Canny(blurred, 100, 200)
image2_edged = cv2.Canny(image2_gray, 100, 200)

# 使用 matplotlib 展示结果
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(cv2.cvtColor(image1_edged, cv2.COLOR_BGR2RGB))
ax[0].set_title("image1 edged")
ax[0].axis('off')
ax[1].imshow(cv2.cvtColor(image2_edged, cv2.COLOR_BGR2RGB))
ax[1].set_title("image2 edged")
ax[1].axis('off')
plt.show()

边缘检测后 截取最大的纯色范围

复制代码
# 寻找边缘检测后的图像中的轮廓
def find_contours(image, edged):
    # 寻找边缘检测后的图像中的轮廓
    contours, _ = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 假设色板是最大的轮廓
    max_contour = max(contours, key=cv2.contourArea)
    x, y, w, h = cv2.boundingRect(max_contour)

    # 提取色板
    palette = image[y+10:y+h-10, x+10:x+w-10]
    return palette

# 对两张图像分别提取色板
palette_image1 = find_contours(image1_gray, image1_edged)
palette_image2 = find_contours(image2_gray, image2_edged)
# 使用 matplotlib 展示结果
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(cv2.cvtColor(palette_image1, cv2.COLOR_BGR2RGB))
ax[0].set_title("Palette from Image 1")
ax[0].axis('off')
ax[1].imshow(cv2.cvtColor(palette_image2, cv2.COLOR_BGR2RGB))
ax[1].set_title("Palette from Image 2")
ax[1].axis('off')
plt.show()

到这里就截取出来可以评估的部分了

干正事吧

评估噪声

复制代码
mean1 = np.mean(palette_image1)
mean2 = np.mean(palette_image2)

median1 = np.median(palette_image1)
median2 = np.median(palette_image2)

std1 = np.std(palette_image1, ddof=1)
std2 = np.std(palette_image2, ddof=1)

print(f"image src 评估的噪声水平: {std1}")
print(f"image ret 评估的噪声水平: {std2}")

fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(palette_image1-mean1)
ax[1].imshow(palette_image2-mean2)
plt.show()
相关推荐
youngong2 小时前
强迫症之用相机快门数批量重命名文件
数码相机·文件管理
weixin_466485113 天前
halcon标定助手的使用
数码相机
诸葛务农5 天前
ToF(飞行时间)相机在人形机器人非接触式传感领域内的应用
数码相机·机器人
塞北山巅5 天前
相机自动曝光(AE)核心算法——从参数调节到亮度标定
数码相机·算法
美摄科技6 天前
相机sdk是什么意思?
数码相机
phyit6 天前
全景相机领域,影石何以杀出重围?
数码相机
鄃鳕6 天前
装饰器【Python】
开发语言·python·数码相机
聪明不喝牛奶6 天前
【已解决】海康威视相机如何升级固件
数码相机
PAQQ6 天前
1站--视觉搬运工业机器人工作站 -- 相机部分
数码相机·机器人
诸葛务农6 天前
人形机器人基于视觉的非接触式触觉传感技术
数码相机·机器人