python-opencv:获取观察同一目标的两个相机图像的映射关系

一、应用背景

目前手上有个项目,在使用主相机去正对观察目标时会因为反光等问题导致采集到的图像存在较多影响图像处理的干扰。遂使用第二个相机做侧向观察。现设计程序建立主副相机的映射关系,统一主副相机坐标。

简略示意图

二、主要opencv函数使用(基于opencv4)

1,findHomography()函数详解点这里(或getPerspectiveTransform()函数详解点这里

这是两个有关获取透视变换矩阵的函数。通过这两个函数就能大致得到两个相机中图像的对应关系,这里findHomography()和getPerspectiveTransform()应该都能满足需求。但后者只能接收4个点,而findHomography()可以根据棋盘图像获取任意数量的点,所以在项目中我只使用了findHomography()函数。

2,findChessboardCornersSB()函数详解点这里

对于相机相对位置的标定,我选择了棋盘标定。这个函数由整合了findChessboardCorners()+cornerSubPix()的功能。实际工作表现非常好,在画质较差的情况下依然能准确识别。

3,drawChessboardCorners(image: Mat, patternSize: Any, corners: Any, patternWasFound: Any)

这个函数用来把棋盘标定findChessboardCornersSB()得到的点按顺序画出来

参数解释
image棋盘格图像
patternSize棋盘格内部角点的行、列数
cornersfindChessboardCorners()输出的角点
patternWasFoundfindChessboardCorners()的返回值

4,warpPerspective(src,M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

获取透视变化后的图像

参数解释
src输入图像矩阵
M3*3的透视变换矩阵,可以通过getPerspectiveTransform/findHomography等函数获取
dsize结果图像大小,为宽和高的二元组
dst输出结果图像,可以省略,结果图像会作为函数处理结果输出
flags可选参数,插值方法的组合(int 类型)
borderMode可选参数,边界像素模式(int 类型)
borderValue可选参数,边界填充值

三、主要代码及步骤

1,画出棋盘格

屏幕上显示棋盘格可以按如下函数执行

    def drawChessboard(self):
        length=400
        width=500
        checkboard_img = np.zeros((length,width))   #这是正方形棋盘格整体大小  分辨率像素:行x列
        block_size=100          #方块大小:边长
        black_block = np.full((block_size,block_size),255) #做一个白色的且边长为block_size的矩阵方块

        for row in range(length//block_size):        #计算行有几个黑块
            for col in range(width//block_size):     #计算列有几个黑块
                if (row+col)%2==0:
                    row_begin = row*block_size
                    row_end = row_begin+block_size
                    col_begin = col*block_size
                    col_end = col_begin+block_size
                    checkboard_img[row_begin:row_end,col_begin:col_end] = black_block     #画白块
        white_background = np.ones((800,1000))#cv2.findChessboardCornersSB函数需要更多的留白
        white_background[200:600,200:700] = checkboard_img#因此将棋盘放入白色背景中
        cv2.imshow("checker_board",white_background)
        cv2.moveWindow("checker_board",0,0)
        cv2.waitKey(0)

棋盘格我这边使用屏幕画出来的,也可以打印出来。
棋盘格
注意:1,棋盘格的长和宽需要设计成不一样的,这样算法能够分清图片的方向。
2,棋盘格周围需要一圈留白增加算法检测图像的成功率。

2,主相机的图像检测

    def main_findCornersInChessboard(self):
		img = cv2.imread("main_camera.jpg")
        ret,corners = cv2.findChessboardCornersSB(img,(3,4))#findChessboardCorners+cornerSubPix
        cv2.drawChessboardCorners(img,(3,4),corners,ret)
        print(corners)
        if ret:
            cv2.imshow('img', img)
            cv2.waitKey(1000)
            cv2.destroyAllWindows()
        return corners

主相机图像

3,副相机图像检测

#同理
def sub_findCornersInChessboard(self):
	img = cv2.imread("sub_camera.jpg")
    ret,corners = cv2.findChessboardCornersSB(img,(3,4))#findChessboardCorners+cornerSubPix
    cv2.drawChessboardCorners(img,(3,4),corners,ret)
    print(corners)
    if ret:
        cv2.imshow('img', img)
        cv2.waitKey(1000)
        cv2.destroyAllWindows()
    return corners

副相机

4,获取副相机里透视变换后的图像

    def getCalibrateInfo(self):
        main_points= self.main_findCornersInChessboard()
        sub_points= self.sub_findCornersInChessboard()
        retval,mask = cv2.findHomography(main_points,sub_points,cv2.RANSAC,10)
        im = cv2.imread(r"sub_camera.jpg")
        dst = cv2.warpPerspective(im,retval,(1080,1280)) #1080*1280是我相机的分辨率

透视变换后的图像

总结

图像对比
这两张图片,左边这张为副相机经透视变换得到的图片。右边这张为主相机得到的图片。观察可以看出,两张图片特征点的像素坐标可以做到对应。这样从副相机中可以初步定位位于主相机中的坐标

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值