Opencv-Python 笔记——双目测距

在假期着手的双目视觉的项目,笔记记在我的印象笔记里。现因为项目需要我把它放在CSDN上,有几张图片无法从印象笔记里导出来所以把链接放在这里,做的时候参考了不少前辈的工作,这里就不先一一感谢了,等项目做到下一步肯定再更新博客的那时再详细地谢谢。印象笔记链接

相机的标定与校准

工具:Matlab、棋盘图(照片)、python
过程:
1、单目:<left/right_distortion= {k1,k2,p1,p2,k3}><lef/rightt_camera_matrix= >
1.1、python:保存相机拍摄的图片;matlab: 相机校准App
1.2、双目各拍摄多张各个角度与位置的棋盘图,分别保存
1.3、导入Matlab

选好选项后进行标定,误差小于0.5MM即可接受,将数据保存到工作区,打开变量
1.4. k1,k2=cameraParma.RD;p1,p2=cmameraParam.TD;k3=0;
1.5. 矩阵的获取:fx、fy是fc的两项,cx,cy是cc的两项

        Focal Length:   fc
        Principal point:    cc
        2、双目:
        2.1、Python:左右目看同一位置的同一幅图像,保存;导入matlab的立体相机工具得到R和T
        3、代码:
#参数
left_camera_matrix = np.array([[692.454591212115, 0., 305.409225800741],
                               [0.,669.698066026769, 264.508936113842],
                               [0., 0., 1.]])#done
left_distortion = np.array([[0.077081711200250,-0.220061292778494,-0.0004968108670932932,0.0006411932375060667,0.000000000000000]])#done



right_camera_matrix = np.array([[674.456695074239, 0., 306.434465883188],
                                [0., 650.163751797273, 256.821019862984],
                                [0., 0., 1.]])#done
right_distortion = np.array([[0.064970360468832,-0.336634672167974,-0.003030799919163,0.003667099404412,0.0000000000000]])#done


R=np.array([[0.999972132749184,-0.00256080461003690,-0.00701256050228641],
		[0.00259579617289607,0.999984204218748,0.00498529389574570],
                    [0.00699968336982408,-0.00500335814702436,0.999962984734923]])#done
T = np.array([-40.0385164688697,0.190937710515179,0.0788520575321127]) # 平移关系向量#done

size = (320,480) # 输入的图像尺寸#done#fixed xy倒置

#进行立体更正#size新图象的

R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv.stereoRectify(left_camera_matrix, left_distortion, right_camera_matrix, right_distortion, size, R,T)

#计算更正map
#相机标定

left_map1, left_map2 = cv.initUndistortRectifyMap(left_camera_matrix, left_distortion, R1, P1, size, cv.CV_16SC2)
right_map1, right_map2 = cv.initUndistortRectifyMap(right_camera_matrix, right_distortion, R2, P2, size, cv.CV_16SC2)

读取操作代码:

import cv2 as cv

cap=cv.VideoCapture(1)
i=0
while True:
	ret,frame=cap.read()
	cv.imshow('frame',frame)
	if cv.waitKey(1)==ord('s'):
		#frame2=cv.cvtColor(frame,cv.COLOR_BGR2GRAY)
		cv.resize(frame,(640480))#图片的大小与标定结果有没有关系?
		cv.imwrite('G:/11hub/op/im%d.jpg'%i,frame)
		i+=1
	if cv.waitKey(1)==ord('q'):
		break
	if cv.waitKey(1)==ord('w'):
		print(frame.shape)
	
	
cap.release()
cv.destroyAllWindows()

分割代码:

def divide_img(frame,i):
	n=1
	m=2
	img = frame
	h = img.shape[0]
	w = img.shape[1]
	dis_h=int(np.floor(h/n))
	dis_w=int(np.floor(w/m))
    
	if i==0:
		sub=img[dis_h*0:dis_h*1,dis_w*0:dis_w*1,:]
	if i==1:
		sub=img[dis_h*0:dis_h*1,dis_w*1:dis_w*2,:]
	return sub

3、校准
3.1、通过双目标定得到摄像头各个参数后采用cv.stereoRectify( )得到校正旋转矩阵R,投影矩阵P、重投影矩阵Q
3.2、通过cv.initUndistortRectifyMap( )得到校准映射参数(left/right_map1/2)
3.3通过cv.remap( )来对输入的左右图像进行校准,其中参数alpha取值-1、01,0自动缩放平移,保留有效像素,01按对应的比例进行缩放,1显示原图像中所有图像,-1自动平移缩放

问题:

  • 图片的大小与结果有没有影响?
  • 代码中size的值有没有影响?

视差图生成

imgL = cv.cvtColor(img1_rectified, cv.COLOR_BGR2GRAY)
imgR = cv.cvtColor(img2_rectified, cv.COLOR_BGR2GRAY)  #转为灰度图为BM算法做准备

stereo = cv.StereoBM_create(numDisparities=16*num, blockSize=blockSize)#BM算法
disparity = stereo.compute(imgL, imgR) #输出视差图

深度图转为伪色彩图

def convertPNG(pngfile):
    # READ THE DEPTH
	im_depth = pngfile
    #apply colormap on deoth image(image must be converted to 8-bit per pixel first)
	im_color=cv.applyColorMap(cv.convertScaleAbs(im_depth,alpha=15),cv.COLORMAP_JET)#cv.convertScaleabs---图像增强
	##im_color=cv.applyColorMap(im_depth,cv.COLORMAP_JET)
	return im_color

得出三维坐标

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐