星座图中格雷映射及其实现

文章介绍了格雷码的概念,它是二进制数字系统的一种排序方式,使得相邻值在比特级别上仅相差一位。在数字通信的星座图调制中,格雷编码用于减少传输错误,特别是在AWGN信道下。通过Python代码展示了如何实现星座图的格雷映射,以及它如何帮助提高信号传输的抗噪性能。
摘要由CSDN通过智能技术生成

在数字信号的调制中,AWGN信道下,星座图一般是采用gray code 进行编码。

本文讲述格雷码的概念及其分析在星座图中格雷编码映射的必要性,最后给出其Python 代码实现。

link: 星座图中格雷映射及其实现

格雷码

先了解一下gray code 的概念:格雷码是二进制数字系统的一种排序方式,使得两个连续值在比特级别上仅仅相差一位。

例如:十进制的1 在自然二进制中的表示通常为001,而2将被编码为010。对应的格雷码为001011。这样,将一个值从1递增至2
对应的编码仅仅需要更改一位比特,而不是两位。

格雷码广泛用于数字通信系统中的纠错1

  • k k k 位二进制数的格雷码序列可以当作 k k k 维空间中的一个超立方体(二维里的正方形,一维里的单位向量)顶点的哈密尔顿回路,其中格雷码的每一位代表一个维度的坐标。

格雷星座映射

在QAM等数字调制方案中,数据通常以4 位或更多位的符号传输,信号的星座图被安排为使得相邻星座点传送的位模式仅相差一位。通过将其与能够纠正单个比特错误的信道编码结合,接收器可以纠正任何导致星座点偏离到相邻点区域的传输错误。这使得传输系统不易受噪声影响。

例如4QAM信号,其自然映射和格雷星座映射为:

:–::–::–::–:
数据比特十进制自然映射格雷映射
000-1-1j-1-1j
011-1+1j-1+1j
1021+1j1-1j
1131-1j1+1j

假设AWGN信道下,某码元发送10 数据比特,接收端采用最大似然判决 y = x + n y=x+n y=x+n, x ^ = arg ⁡ min ⁡ x ∣ ∣ y − x ∣ ∣ \hat{x}=\arg\min_x ||y-x|| x^=argminx∣∣yx∣∣ ,采用不同映射,有以下情形:

  • 自然:对应发送1+1j ,有 P 1 P_1 P1 的概率被判决为1-1j(即判为11,误比特数1个), P 1 P_1 P1的 概率被判决为01(误比特2个), P 2 ( P 2 < P 1 ) P_2(P_2<P_1) P2(P2<P1) 的概率被判决为00(误比特1个) ,那么平均误比特 3 P 1 + P 2 3P_1+P_2 3P1+P2
  • 格雷:对应发送1-1j, P 1 P_1 P1 的概率判决为1100,均误比特1个, P 2 P_2 P2的概率判为01,误比特 2 P 1 + 2 P 2 2P_1+2P_2 2P1+2P2
  • 3 P 1 + P 2 > 2 P 1 + 2 P 2 3P_1+P_2>2P_1+2P_2 3P1+P2>2P1+2P2

发送其余数据比特时,情形类似。可以发现AWGN信道下格雷映射方案的BER性能是优于自然映射的。相比于正常二进制映射,使用格雷码可以降低总体错误率。这也是星座映射采用格雷映射的原因。

格雷码的构造2

我们观察以下 n n n 维的二进制和其格雷码 G ( n ) G(n) G(n)。如果 G ( n ) G(n) G(n) 的二进制第 i i i 位为1,仅当 n n n 的二进制第 i i i 位为 1,第 i + 1 i+1 i+1 位为 0 0 0 或者 第 i i i 位为 0 ,第 i + 1 i+1 i+1 位为 1。于是可以当成一个异或运算:

G ( n ) = n ⊕ ⌊ n 2 ⌋ G(n)=n\oplus \lfloor\frac{n}{2}\rfloor G(n)=n2n

int g(int n) { return n ^ (n >> 1); }

代码实现

  • 二维QAM格雷映射基于这样一种思想: 如果每一维是格雷映射的,那么他们的笛卡尔积也是格雷的。即两个gray mapping 的PAM映射组合起来就是QAM gray mapping.
  • 二维的PSK gray mapping 和一维PAM gray mapping 类似。
Python 实现
import numpy as np
def qam_constellation(M,normalize=False):
    """ M must be 2^k ,where k is an even integer
    gray mapping
    param:
        - M: the size of qam set
        - normalize: normalize the average energy qam symbols unit
    return:
        1-D numpy array
    """
    assert np.log2(M).is_integer()
    m = int(np.sqrt(M))
    x = np.zeros(m,np.int32) # gray mapping binding to natural number
    y = np.zeros(m,np.int32) 
    # mappping natural number to gray code in octal
    natural2gray = lambda x: x ^ (x >> 1)
    x[natural2gray(np.arange(0, m))] =  np.arange(0, 2*m,2) -m+1
    y[natural2gray(np.arange(0, m))] =  np.arange(0, 2*m,2) -m+1


    constellation = np.zeros((m, m), dtype=np.cfloat)
    for i in range(m):
        for j in range(m):
            constellation[i][j] = (x[i]+1j* y[j])
    if normalize:
        return constellation.flatten()/(np.linalg.norm(constellation)/m)
    else:
        return constellation.flatten()


def psk_constellation(M):
    """ 
    gray mapping
    param:
        - M: the size of psk set
        - normalize: normalize the average energy qam symbols unit
    return:
        1-D numpy array
    """
    phase = np.arange(0, M) * 2 * np.pi / M
    constellation = np.zeros(M, dtype=np.cfloat)
    natural2gray = lambda x: x ^ (x >> 1)
    constellation[natural2gray(np.arange(0, M))] = np.exp(1j * phase)
    return constellation

def mapping(data, constellation):
    """
    param:
        - data: binary data in 1-D numpy array
        - constellation: 1-D numpy array
    return:
        1-D numpy array
    """
    M = len(constellation)
    assert np.log2(M).is_integer()
    assert len(data) % np.log2(M) == 0
    data = data.reshape(-1, int(np.log2(M)))
    mask = np.array([2**i for i in range(int(np.log2(M))-1, -1, -1)]) # [8,4,2,1]
    index = np.sum(data * mask, axis=1) # left first
    return constellation[index]



if __name__ == "__main__":
    qam_16 = qam_constellation(16)
    psk_4 = psk_constellation(4)
    print(qam_16)
    print(psk_4)
    binary_data = np.random.randint(0, 2, 128)
    psk_symbols = mapping(binary_data, psk_4)
    qam_symbols = mapping(binary_data, qam_16)
    print(psk_symbols)
    print(qam_symbols)

  1. gray code wiki ↩︎

  2. 格雷码 ↩︎

### 回答1: 格雷码相移结构光是一种用于三维测量的光学方法。它通过在物体前面投射不同的格雷码图案,利用相机采集到的图像进行解码和计算,从而得到三维物体的形状信息。 在Matlab实现格雷码相移结构光,需要进行以下步骤: 1. 生成格雷码图案:首先确定需要生成的格雷码图案数目,即相移图案的数量。然后,使用Matlab的图像处理工具箱的函数生成相应数量的格雷码图案。 2. 投射格雷码图案:将生成的格雷码图案投射到物体上,可以使用投影仪或激光器来实现。每个格雷码图案需要在一定的时间间隔内依次投射。 3. 采集图像:在每个格雷码图案投射完毕后,使用相机采集对应的图像。确保相机设置正确,使得图像清晰可见。 4. 图像解码:对每个格雷码图案的图像进行解码。可以使用Matlab的图像处理工具箱的函数,比如灰度阈值分割、轮廓提取等方法,将格雷码图案从图像分割提取出来。 5. 计算三维形状:根据格雷码图案的解码结果,进行三维形状的计算。常用的方法包括三角测量法、相位解包法等。一般需要根据具体的应用需求选择适合的算法。 6. 可视化结果:最后,将计算得到的三维形状结果进行可视化展示。可以使用Matlab的绘图函数,将三维形状呈现出来,便于分析和观察。 总结来说,Matlab实现格雷码相移结构光主要包括生成格雷码图案、投射图案、采集图像、图像解码、三维形状计算和结果可视化等步骤。通过这些步骤的组合,可以实现对三维物体形状的测量。 ### 回答2: 格雷码相移结构光是一种常用的光学显微成像技术,它通过使用相位编码和结构光投影,可以实现高分辨率的三维成像。 在MATLAB实现格雷码相移结构光,可以按照以下步骤进行: 1. 生成格雷码序列:先确定需要的相移步长,然后生成对应的格雷码序列。格雷码序列根据皮次序列的规律,保证相邻的格雷码只有一位(bit)不同。可以使用MATLAB的编程语言来生成这个序列。 2. 生成结构光图案:根据格雷码序列,生成相应的结构光图案。可以使用MATLAB的图像处理工具箱来实现这一步骤。结构光图案的生成一般采用二进制编码的方式,即将格雷码序列的0和1映射为不同的灰度值。 3. 光学显微成像:将生成的结构光图案投影到被测物体上,并使用合适的光学装置进行成像。通过改变相移步长和相移周期,可以获得不同的深度信息。被测物体的三维形态可以通过对多个相移周期的图像进行处理和重建得到。 总结起来,MATLAB可以通过生成格雷码序列和结构光图案来实现格雷码相移结构光。结合光学装置进行成像,可以得到被测物体的三维形态信息。 ### 回答3: 格雷码相移结构光是一种光学编码技术,通过相位调制和空间光调制器(SLM)生成具有特定格雷码编码的光场,实现空间光调制和相位解码。在Matlab实现格雷码相移结构光需要进行以下步骤: 1. 设计格雷码编码序列:首先确定要编码的信息,然后使用格雷码生成算法生成相应的格雷码编码序列。格雷码优于二进制码的地方在于,任意两个相邻码的汉明距离为1,能减小误码率。 2. 计算格雷码对应的相位偏移:根据格雷码编码序列的长度,计算位于光场上不同位置的格雷码对应的相位偏移。通常,格雷码0和1的相位偏移值是0和π。 3. 生成格雷码相移结构光场:使用Matlab的图像处理工具箱,可以创建一个与格雷码编码序列长度相匹配的图像矩阵,然后根据格雷码对应的相位偏移值,将相应位置的像素值设置为相应的相位值。 4. 显示和解码:通过SLM显示生成的格雷码相移结构光场,然后使用相应的相位解码算法,对接收到的光信号进行解码,从而获取原始编码信息。 总之,通过以上步骤,在Matlab可以实现格雷码相移结构光的生成和解码。这种技术在三维形貌测量、光学显微成像等领域具有重要的应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值