Python模拟实现CMOS传感器的两种降采样方式(Binning和Skipping)

在通常的摄像头中,不同的resolution对应不同的帧率。想要提高帧率就要考虑是否需要缩小视野(FOV)。
若不希望视野缩小,就需要减少resolution。
常用的减少resolution的两种方式是下采样:Skipping and Binning。
Skipping
通过选取视野中的像素点,抽取指定像素点来降低分辨率。在Skipping模式中,并不会对所有行列的像素点进行采样,这样才能获取非原始分辨率的图像(降低的分辨率图像)。行列数据是成对读取的。
Binning
Binning是将相邻像元(相同颜色)感应的电荷加在一起,以一个像素的模式读出。在环境光照低的情况下,提高摄像头表现力。需要配合Skipping一起使用。
想更加了解可以看连接:https://zhuanlan.zhihu.com/p/583948933
下面我们使用Python模拟实现上述两种算法。
首先,由于CMOS的两种降采样在raw域去做的,所以我们现将jpg转为灰度形式保存图片,我们这里采用1920*1080分辨率的图像来模拟。
转灰度并且保存

# -*-coding:utf-8-*-
import cv2
image=cv2.imread('test.jpeg')
image=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imwrite('gray.jpeg',image)

Binning实现

def binning(path):
    bayer = cv2.imread(path, cv2.IMREAD_GRAYSCALE).astype(np.float32) 
    print('img', bayer.shape)
    Nimg = np.zeros((bayer.shape[0] // 2, bayer.shape[1] // 2, 1))
    print('Nimg', Nimg.shape)
    for i in range(Nimg.shape[0]):#540
        for j in range(Nimg.shape[1]):  #960
            if i % 2 == 0 and j % 2 == 0:
                Nimg[i, j] = (bayer[i * 2, j * 2] + bayer[i * 2, j * 2 + 2] + bayer[i * 2 + 2, j * 2]
                               + bayer[i * 2 + 2, j * 2 + 2]) / 4.
            elif i % 2 == 0 and j % 2 == 1:
                Nimg[i, j] = (bayer[i * 2, j * 2 - 1] + bayer[i * 2, j * 2 + 1] + bayer[i * 2 + 1, j * 2 - 1] + bayer[
                    i * 2 + 1, j * 2 + 1]) / 4.
            elif i % 2 == 1 and j % 2 == 0:
                Nimg[i, j] = (bayer[i * 2 - 1, j * 2] + bayer[i * 2 - 1, j * 2 + 2] + bayer[i * 2 - 1, j * 2] + bayer[
                    i * 2 + 1, j * 2 + 2]) / 4.
            elif i % 2 == 1 and j % 2 == 1:
                Nimg[i, j] = (bayer[i * 2 - 1, j * 2 - 1] + bayer[i * 2 - 1, j * 2 + 1] + bayer[
                    i * 2 - 1, j * 2 - 1] + bayer[i * 2 + 1, j * 2 + 1]) / 4.
            else:
                print("Bining ERROR!")
    cv2.imwrite('binning.jpg', Nimg)
    print('Bining Done!')

Skipping实现

def skiping(path):
    img = cv2.imread(path, cv2.IMREAD_GRAYSCALE).astype(np.float32)
    Nimg = np.zeros((img.shape[0] // 2, img.shape[1] // 2, 1))
    for i in range(Nimg.shape[0]):  # 540
        for j in range(Nimg.shape[1]):  # 960
            for k in range(Nimg.shape[2]):
                if i % 2 == 0 and j % 2 == 0:
                    Nimg[i, j] = img[i * 2, j * 2]
                elif i % 2 == 0 and j % 2 == 1:
                    Nimg[i, j] = img[i * 2, j * 2 - 1]
                elif i % 2 == 1 and j % 2 == 0:
                    Nimg[i, j] = img[i * 2 - 1, j * 2]
                elif i % 2 == 1 and j % 2 == 1:
                    Nimg[i, j] = img[i * 2 - 1, j * 2 - 1]
                else:
                    print(i, j)
                    print("ERROR")
    cv2.imwrite('skiping.jpg', Nimg)
    print('skiping Done!')

整体代码如下:

# -*-coding:utf-8-*-
import cv2
import numpy as np
def binning(path):
    bayer = cv2.imread(path, cv2.IMREAD_GRAYSCALE).astype(np.float32)
    print('img', bayer.shape)
    Nimg = np.zeros((bayer.shape[0] // 2, bayer.shape[1] // 2, 1))
    print('Nimg', Nimg.shape)
    for i in range(Nimg.shape[0]):
        for j in range(Nimg.shape[1]):  # 960
            if i % 2 == 0 and j % 2 == 0:
                Nimg[i, j] = (bayer[i * 2, j * 2] + bayer[i * 2, j * 2 + 2] + bayer[i * 2 + 2, j * 2]
                               + bayer[i * 2 + 2, j * 2 + 2]) / 4.
            elif i % 2 == 0 and j % 2 == 1:
                Nimg[i, j] = (bayer[i * 2, j * 2 - 1] + bayer[i * 2, j * 2 + 1] + bayer[i * 2 + 1, j * 2 - 1] + bayer[
                    i * 2 + 1, j * 2 + 1]) / 4.
            elif i % 2 == 1 and j % 2 == 0:
                Nimg[i, j] = (bayer[i * 2 - 1, j * 2] + bayer[i * 2 - 1, j * 2 + 2] + bayer[i * 2 - 1, j * 2] + bayer[
                    i * 2 + 1, j * 2 + 2]) / 4.
            elif i % 2 == 1 and j % 2 == 1:
                Nimg[i, j] = (bayer[i * 2 - 1, j * 2 - 1] + bayer[i * 2 - 1, j * 2 + 1] + bayer[
                    i * 2 - 1, j * 2 - 1] + bayer[i * 2 + 1, j * 2 + 1]) / 4.
            else:
                print("Bining ERROR!")
    cv2.imwrite('binning.jpg', Nimg)
    print('Bining Done!')



def skiping(path):
    img = cv2.imread(path, cv2.IMREAD_GRAYSCALE).astype(np.float32)
    Nimg = np.zeros((img.shape[0] // 2, img.shape[1] // 2, 1))
    for i in range(Nimg.shape[0]):  # 540
        for j in range(Nimg.shape[1]):  # 960
            for k in range(Nimg.shape[2]):
                if i % 2 == 0 and j % 2 == 0:
                    Nimg[i, j] = img[i * 2, j * 2]
                elif i % 2 == 0 and j % 2 == 1:
                    Nimg[i, j] = img[i * 2, j * 2 - 1]
                elif i % 2 == 1 and j % 2 == 0:
                    Nimg[i, j] = img[i * 2 - 1, j * 2]
                elif i % 2 == 1 and j % 2 == 1:
                    Nimg[i, j] = img[i * 2 - 1, j * 2 - 1]
                else:
                    print(i, j)
                    print("ERROR")
    cv2.imwrite('skiping.jpg', Nimg)
    print('skiping Done!')

def test(path):
    binning(path)
    skiping(path)

if __name__ == "__main__":
    test('gray.jpeg')

原图19201080:
在这里插入图片描述灰度图1920
1080:
在这里插入图片描述以下两种是两种降采样结果,分辨率是1920/2,1080/2,从肉眼看并无明显区别。
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值