一、什么是格雷码
**格雷码(Gray Code)**是一种特殊的二进制编码:
相邻两个数只有 1 位不同
| 十进制 | 二进制 | 格雷码 |
|---|---|---|
| 0 | 000 | 000 |
| 1 | 001 | 001 |
| 2 | 010 | 011 |
| 3 | 011 | 010 |
| 4 | 100 | 110 |
| 5 | 101 | 111 |
| 6 | 110 | 101 |
| 7 | 111 | 100 |
核心特点
相邻值 → 只变1位
二、为什么要用格雷码(工业意义)
普通二进制:
011 → 100(变化3位)
问题:
容易出错(噪声/遮挡)
格雷码:
011 → 010(只变1位)
优势:
抗噪声强
鲁棒性高
三、数学原理
二进制 → 格雷码
公式:

cpp
举例
二进制:
B = 1011
右移:
B>>1 = 0101
异或:
1011
⊕0101
-----
1110
格雷码:
1110
格雷码 → 二进制(逆过程)
递推:

四、结构光中的格雷码
在结构光中:
投影仪 → 投影编码条纹
相机 → 拍摄
每一位 = 一张图
例如 8位格雷码:
需要 8 张图
每张图:
黑白条纹
解码过程
对每个像素:
看每一帧是亮还是暗
→ 得到bit序列
→ 转换为整数
得到:
像素对应投影位置
五、MATLAB OpenCV生成格雷码
Matlab
生成格雷码序列
cpp
n = 3; % 位数
N = 2^n;
gray = bitxor((0:N-1), floor((0:N-1)/2));
disp(gray)

转成二进制矩阵
cpp
bin = de2bi(gray, n, 'left-msb');
disp(bin)

生成条纹图像
cpp
width = 256;
height = 200;
n = 8;
for i = 1:n
pattern = zeros(height, width);
for x = 1:width
g = bitxor(x-1, floor((x-1)/2));
bit = bitget(g, n-i+1);
pattern(:, x) = bit;
end
imshow(pattern, []);
pause(0.5);
end

OpenCV 生成格雷码(结构光模块)
cpp
OpenCV提供:
cv::structured_light::GrayCodePattern
C++ 示例
#include <opencv2/opencv.hpp>
#include <opencv2/structured_light.hpp>
using namespace cv;
using namespace cv::structured_light;
int main()
{
int width = 1024;
int height = 768;
Ptr<GrayCodePattern> graycode =
GrayCodePattern::create(width, height);
std::vector<Mat> patterns;
graycode->generate(patterns);
for (int i = 0; i < patterns.size(); i++)
{
imshow("pattern", patterns[i]);
waitKey(200);
}
}
输出内容
patterns:
- 正码
- 反码
- 多bit编码图
六、流程
采集 N 张图
↓
每个像素:
判断亮/暗
↓
得到 Gray Code
↓
转换为 Binary
↓
得到列坐标
优点
- 抗噪声
- 不易误码
- 结构简单
缺点
- 分辨率有限(整数级)
- 需要多帧图像
Q1:为什么格雷码抗噪声?
相邻只变1位 → 错误不会级联
Q2:为什么要配合相位法?
格雷码:整数精度
相位法:亚像素精度
Q3:最少需要多少张图?

Q4:作用
格雷码 = 相邻只变1位的编码
→ 用于稳定获取离散位置
→ 结构光中用于"粗定位"