@TangWill
2019-07-26T12:10:29.000000Z
字数 8433
阅读 823
大创
# -*- coding: utf-8 -*-from PIL import Imageimport osdef de_bruijn(k, n):"""de Bruijn sequence for alphabet kand subsequences of length n."""try:# let's see if k can be cast to an integer;# if so, make our alphabet a list_ = int(k)alphabet = list(map(str, range(k)))except (ValueError, TypeError):alphabet = kk = len(k)a = [0] * k * nsequence = []def db(t, p):if t > n:if n % p == 0:sequence.extend(a[1:p + 1])else:a[t] = a[t - p]db(t + 1, p)for j in range(a[t - p] + 1, k):a[t] = jdb(t + 1, t)db(1, 1)return "".join(alphabet[i] for i in sequence)if __name__ == "__main__":DB = de_bruijn(3, 3)DB_list = list(DB)print(DB_list)x = 912y = 1140c = Image.new("RGB", (x, y))skip = Falsei = 0while i < x:for k in range(0, 15):rgb = 255 - (5*(k - 7) ** 2)temp = int(i / 20)if temp < 27:for j in range(0, y):if i % 20 == 0:for m in range(0, 5):c.putpixel([i + m + 186, j], (0, 0, 0))i = i + 5skip = Falseelif DB_list[temp] == "0":c.putpixel([i + k + 186, j], (rgb, 0, 0))skip = Trueelif DB_list[temp] == "1":c.putpixel([i + k + 186, j], (0, rgb, 0))skip = Trueelif DB_list[temp] == "2":c.putpixel([i + k + 186, j], (0, 0, rgb))skip = Trueif skip:i = i + 15else:i = i + 1c.show()c.save("structured_light .bmp")
main.m
clear all; clc; %清空变量%--------------------------------------------------------------% 0:red,1:green,2:blue% num: 为debruijn序列,包含红绿蓝3种颜色,window size为3% num序列总长度为3^3 = 27% 原投影图案生成方法:% (1).原投影图片大小竖直方向1140像素,水平方向912像素% (2).每个条纹水平方向长度15个像素,第一个条纹中心位于第8个像素位置% 因此条纹中心像素坐标为8+(i-1)*20% map: map(i,j,k)表示连续三个颜色为(i,j,k)的三元组i颜色对应的条纹中心位置% 例如map(0,0,0)=8,因为三个连续红条纹在开始的位置,第一个红条纹中心为8% map(1,0,0)=68, 绿红红位于第4个位置,68为绿条纹中心%--------------------------------------------------------------num = [0, 0, 0, 1, 0, 0, 2, 0, 1, 1, 0, 1, 2, 0, 2, 1, 0, 2, 2, 1, 1, 1, 2, 1, 2, 2, 2];map = zeros(3,3,3);for i=1:25map(num(i)+1,num(i+1)+1,num(i+2)+1) = 8 + (i-1)*20;end%--------------------------------------------------------------% R12: 由相机到投影仪的旋转矩阵 3*3% T12: 由相机到投影仪的平移矩阵 1*3% Kc1: 相机内参矩阵 3*3% Kp2: 投影仪内参矩阵 3*3% Hc1: 相机单应性矩阵 3*4% Hp2: 投影仪单应性矩阵 3*4%--------------------------------------------------------------R12 = [9.7516454746001247e-001 -7.7281024823287244e-003 2.2134674564838733e-001;5.4950021604755926e-004 9.9947240635257240e-001 3.2474713075112072e-002;-2.2148093242223318e-001 -3.1546558795230203e-002 9.7465430343355963e-001];T12 = [-1.4326112323874105e+002 2.0614986909838471e+001 -1.0037865572591169e+001];Kc1 = [2.1363192826189816e+003 0. 6.4087239901301598e+002;0. 2.1377724542629630e+003 4.9766519824009470e+002;0. 0. 1.];Kp2 = [1.7342859113112791e+003 0. 4.5022560667574703e+002;0. 3.4614881021035653e+003 5.2438368036642009e+002;0. 0. 1.];Hp2 = Kp2*[R12,T12'];Hc1 = Kc1*[eye(3,3),zeros(3,1)];img12 = imread('2.png'); %读取图片imshow(img12);[flag12,color_flag12] = feature_point(img12); %提取特征,详情见函数内部注释figure;imshow(color_flag12);[num_coord12, coord12] = reconstruction(color_flag12,Hc1,Hp2,map); %三维坐标重建,详情见函数内部注释figure;scatter3(coord12(:,1),coord12(:,2),coord12(:,3),2) %画三维离散点图
feature.m
%--------------------------------------------------------------%条纹特征点提取,包括条纹中心点的位置和对应的颜色%1:red,2:green,3:blue%输入参数IMG: 大小n*m*3,表示输入三通道彩色图片%输出参数flag: 大小n*m, 表示对应像素是否是条纹中心% flag(i,j)=1表示(i,j)位置是条纹中心,flag的值为0或1%输出参数color_flag: 大小n*m,表示对应条纹中心的颜色% color_flag(i,j)=2代表(i,j)位置条纹中心颜色为绿色% color_flag(i,j)=0代表该位置不是条纹中心%--------------------------------------------------------------function [flag, color_flag] = feature_point(IMG)IMG_gray = rgb2gray(IMG); %彩色图转灰度图flag = zeros(1024,1280); %初始化color_flag = zeros(1024,1280); %初始化linyu = 5; %一个阈值,可自取%i和j的范围代表物体在图片的这个范围内,限制范围可以增加计算速度,可自取for i=300:880for j=500:1000if IMG_gray(i,j)<10 %如果灰度图的对应像素值小于10认为该点为黑色背景continue;end% temp为以(i,j)为中心长度为2*linyu+1的图像灰度数组temp = IMG_gray(i,j-linyu:j+linyu);% 如果当前中心点的灰度值是这个邻域中的最大值,那么认为该点是条纹中心[~,da] = max(temp);if da == linyu+1flag(i,j)=1;endendendfor i=300:880for j=500:1000if flag(i,j)==0 %如果不是条纹中心则跳过continue;end%灰度图片,如果灰度值大于150认为该点是白色条纹中心% if IMG_gray(i,j)>150% color_flag(i,j)=4;% continue;% end%彩色图片,如果第一个通道比另外两个通道值大,认为该位置是红色条纹中心if IMG(i,j,1)>IMG(i,j,2) && IMG(i,j,1)>IMG(i,j,3)color_flag(i,j)=1;continue;end%彩色图片,如果第二个通道比另外两个通道值大,认为该位置是绿色条纹中心if IMG(i,j,2)>IMG(i,j,1) && IMG(i,j,2)>IMG(i,j,3)color_flag(i,j)=2;continue;end%彩色图片,如果第三个通道比另外两个通道值大,认为该位置是蓝色条纹中心if IMG(i,j,3)>IMG(i,j,2) && IMG(i,j,3)>IMG(i,j,1)color_flag(i,j)=3;continue;endendendend
reconstruction.m
%--------------------------------------------------------------%物体三维坐标点重建%输入参数color_flag: 对应feature_point函数的第二个输出%输入参数Hc: 相机单应性矩阵%输入参数Hp: 投影仪单应性矩阵%输入参数map: 主函数开始的那个map数组%输出参数num_coord: 输出三维点的数目%输出参数coord: 输出三维点的坐标%--------------------------------------------------------------function [num_coord, coord] = reconstruction(color_flag,Hc,Hp,map)num_coord = 0; %初始化for i=300:880ind = 0;loc = zeros(1,100);%将图片第i行的所有条纹中心临时存储在loc中for j=500:1000if color_flag(i,j)~=0ind = ind+1;loc(ind) = j;endendif (ind<3) % 如果少于3个中心则无法重建continue;endfor j = 1:ind-2A = zeros(3,3);num_coord = num_coord+1;A(1,:) = Hc(3,1:3).*loc(j)-Hc(1,1:3);A(2,:) = Hc(3,1:3).*i-Hc(2,1:3);A(3,:) = Hp(3,1:3).*map(color_flag(i,loc(j)),color_flag(i,loc(j+1)),color_flag(i,loc(j+2)))-Hp(1,1:3);ydx = A\[Hc(1,4)-Hc(3,4)*loc(j);Hc(2,4)-Hc(3,4)*i;Hp(1,4)-Hp(3,4)*map(color_flag(i,loc(j)),color_flag(i,loc(j+1)),color_flag(i,loc(j+2)))];% 设定一下和相机的距离,如果过近或者过远显然都是噪声点,可自取% if ydx(3)>1000 || ydx(3)<500% continue;% endcoord(num_coord,:) = ydx';end% debruijn序列最后两个条纹仍利用最后三个颜色重建for j=ind-1:indif j==ind-1A = zeros(3,3);num_coord = num_coord+1;A(1,:) = Hc(3,1:3).*loc(j)-Hc(1,1:3);A(2,:) = Hc(3,1:3).*i-Hc(2,1:3);A(3,:) = Hp(3,1:3).*(map(color_flag(i,loc(j-1)),color_flag(i,loc(j)),color_flag(i,loc(j+1)))+15)-Hp(1,1:3);ydx = A\[Hc(1,4)-Hc(3,4)*loc(j);Hc(2,4)-Hc(3,4)*i;Hp(1,4)-Hp(3,4)*(map(color_flag(i,loc(j-1)),color_flag(i,loc(j)),color_flag(i,loc(j+1)))+15)];% if ydx(3)>1000 || ydx(3)<500% continue;% endcoord(num_coord,:) = ydx';elseif j==indA = zeros(3,3);num_coord = num_coord+1;A(1,:) = Hc(3,1:3).*loc(j)-Hc(1,1:3);A(2,:) = Hc(3,1:3).*i-Hc(2,1:3);A(3,:) = Hp(3,1:3).*(map(color_flag(i,loc(j-2)),color_flag(i,loc(j-1)),color_flag(i,loc(j)))+30)-Hp(1,1:3);ydx = A\[Hc(1,4)-Hc(3,4)*loc(j);Hc(2,4)-Hc(3,4)*i;Hp(1,4)-Hp(3,4)*(map(color_flag(i,loc(j-2)),color_flag(i,loc(j-1)),color_flag(i,loc(j)))+30)];% if ydx(3)>1000 || ydx(3)<500% continue;% endcoord(num_coord,:) = ydx';endendendend
未注释部分参考公式:
式中,表示的是矩阵的第行和第列元素。将两个式子整理后得到关于、和的三元一次方程,








<?xml version="1.0"?><opencv_storage><Kc type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>2.1363192826189816e+003 0. 6.4087239901301598e+002 0.2.1377724542629630e+003 4.9766519824009470e+002 0. 0. 1.</data></Kc><kc type_id="opencv-matrix"><rows>5</rows><cols>1</cols><dt>d</dt><data>-5.6850946659891023e-002 2.6322763056141931e+000-1.1377015012654045e-003 1.6506197473016759e-003-2.1654415041354078e+001</data></kc><Kp type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>1.7342859113112791e+003 0. 4.5022560667574703e+002 0.3.4614881021035653e+003 5.2438368036642009e+002 0. 0. 1.</data></Kp><kp type_id="opencv-matrix"><rows>5</rows><cols>1</cols><dt>d</dt><data>9.6270780483633647e-002 -8.0172849754942543e+000-2.6246483366578217e-003 2.3503112604238339e-0032.2313956040160841e+002</data></kp><Rp type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>9.8817697193050202e-001 -2.7706101018562532e-0031.5329251731877641e-001 1.1226239513894419e-0029.9846035682073886e-001 -5.4322071055690473e-002-1.5290599626123413e-001 5.5400718199914163e-0029.8668663552836944e-001</data></Rp><Tp type_id="opencv-matrix"><rows>3</rows><cols>1</cols><dt>d</dt><data>-1.5168118625605635e+002 1.7918489397033632e+001-5.3101094723810185e+001</data></Tp><cam_error>6.0649322922523355e-002</cam_error><proj_error>1.5337621234636628e-001</proj_error><stereo_error>1.3013498108534971e-001</stereo_error><frameWidth>1280</frameWidth><frameHeight>1024</frameHeight><screenResX>0</screenResX><screenResY>0</screenResY></opencv_storage>