久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

生成黑白棋盤標(biāo)定圖和單目相機標(biāo)定(python+opencv實現(xiàn))

 bit54song 2020-04-05

學(xué)習(xí)記錄。

事實上很早就接觸過視覺定位這東西,,但是到現(xiàn)在才返回頭學(xué)習(xí)一下相機的標(biāo)定,,真是可恥啊,!我把想法和過程記錄一下,。

相機成像

相機的成像原理——小孔成像

然而,,在實際由于設(shè)計工藝問題、相機安裝環(huán)境或物體擺放位置等影響,,會照成成像與實際圖像不一樣的現(xiàn)象,。

由于設(shè)計工藝照成的影響是無法改變的事實,所以這將是相機的內(nèi)參,;

由環(huán)境或安裝方式照成的影響是可以改變的,,這就是相機的外參。

https://blog.csdn.net/aoulun/article/details/78768570中詳細介紹了相機成像原理,,相機內(nèi),、外參數(shù)是什么。這里為了保證記錄的完整型,,把成像平面的像素座標(biāo)與實際物體的世界座標(biāo)公式寫下來,。

1.紅框就是相機外參,R為旋轉(zhuǎn)矩陣,,T為平移向量,;如果相機鏡頭和物體平面平行(室內(nèi)定位中,有一種基于視覺的室內(nèi)定位,,定位方式就是在移動的小車上安裝單目相機,,在屋頂安裝各種可識別的標(biāo)簽,相機的光軸一直與屋頂是垂直的),,在這種情況下,旋轉(zhuǎn)矩陣可以看作是單位向量及R=E,,而平移向量T=0,。

2.藍框就是相機的內(nèi)參,相機的內(nèi)參從出廠后就被固定了,。

f:相機的焦距

(u0,v0):像平面的投影中心點

dx,dy:就是單位像素對應(yīng)實際距離

Zc:可以認為相機鏡頭到成像物體的垂直距離

對這部分我就不贅述了,,在麻呱智能 的文章中介紹的特別詳細,我就不班門弄斧了,。

生成棋盤標(biāo)定圖

創(chuàng)建自定義的棋盤標(biāo)定圖,,這個沒啥要說的,就是調(diào)用了opencv的畫矩形框的函數(shù),,代碼如下:

#生成想要的標(biāo)定圖,,大小自定義
import cv2
import sys

#讀入一張空白圖片,該圖片最好和你想要標(biāo)定的相機分辨率一致
image = cv2.imread('C:\\Users\\wlx\\Documents\\py_study\\camera calibration\\white.jpg')
#設(shè)置圖片上黑白方格
dpi = 96                                                #dpi自己電腦上一英寸顯示的像素個數(shù)
cm_to_inch = 0.3937                                     #1cm = 0.3937inch
square_length = 1.5                                     #黑白方格邊長1.5cm
x_nums = 10                                             #x方向畫10個方格
y_nums = 8                                              #y方向畫8個方格
square_pixel = int(square_length * cm_to_inch * dpi)    #方格邊長的像素
#為了把方格圖像放在紙張的中間,設(shè)定起始座標(biāo)
x0 = 40
y0 = 16

#畫方格
def DrawSquare():
    flag = -1                                            #顏色轉(zhuǎn)變標(biāo)志
    #一行一行的畫
    for i in range(y_nums):
        #每畫一行先換一次顏色
        flag = 0 - flag
        for j in range(x_nums):
            if flag > 0:
                color = [0,0,0]                          #黑色方格
            else:
                color = [255,255,255]
            #調(diào)用opencv中的畫方框函數(shù)
            cv2.rectangle(image,(x0 + j*square_pixel,y0 + i*square_pixel),
                          (x0 + j*square_pixel+square_pixel,y0 + i*square_pixel+square_pixel),color,-1)
            flag = 0 - flag
    #保存圖像
    cv2.imwrite('chess_map.jpg',image)

#判斷本程序是獨立運行還是被調(diào)用
if __name__ == '__main__':
    DrawSquare()

上面的代碼可以生成自己想要的棋盤標(biāo)定圖,,修改x_nums和y_nums參數(shù)的值,,就能獲得任意數(shù)量的黑白格子。實現(xiàn)原理就是在圖像的某一點開始,,先畫一個黑色方格(或者白色),畫完后將起點座標(biāo)和終點座標(biāo)都向右移動方格邊長的距離,,然后改變顏色再畫一個方格,,依次類推,畫完一行后,,就轉(zhuǎn)戰(zhàn)到第二行,,直到全部完成。

注意:在圖像上座標(biāo)是這樣的

cv2.rectangle(img,pt1,pt2,color,thickness=None,line_type=None,shift=None)

img:圖像,,要畫圖的圖像

pt1:方格的起點座標(biāo)(x0,y0)

pt2:方格的終點座標(biāo)(x1,y1)

color:方框的顏色

thickness:方框線的寬度(像素),當(dāng)值為負數(shù)時,,填充方框

line_type:方框線的樣式

采集標(biāo)定圖

我采用離線標(biāo)定,先把不同角度的標(biāo)定圖采集保存下來,,然后再開始標(biāo)定,。下面是采集的代碼

import cv2
import os

#標(biāo)定圖像保存路徑
photo_path = "C:\\Users\\wlx\\Documents\\py_study\\camera calibration\\image"
#創(chuàng)建路徑
def CreateFolder(path):
    #去除首位空格
    del_path_space = path.strip()
    #去除尾部'\'
    del_path_tail = del_path_space.rstrip('\\')
    #判讀輸入路徑是否已存在
    isexists = os.path.exists(del_path_tail)
    if not isexists:
        os.makedirs(del_path_tail)
        return True
    else:
        return False
#獲取不同角度的標(biāo)定圖像
def gain_photo(photo_path):
    # 檢查輸入路徑是否存在——不存在就創(chuàng)建
    CreateFolder(photo_path)
    #開啟攝像頭
    video = cv2.VideoCapture(0)
    #顯示窗口名稱
    photo_window = 'calibration'
    #保存的標(biāo)定圖像名稱以數(shù)量命名
    photo_num = 0
    while video.isOpened():
        ok,frame = video.read()                                 #讀一幀的圖像
        if not ok:
            break
        else:
            cv2.imshow(photo_window,frame)
            key = cv2.waitKey(10)
            #按鍵盤‘A’保存圖像
            if key & 0xFF == ord('a'):
                photo_num += 1
                photo_name = photo_path + '\\' + str(photo_num) + '.jpg'
                cv2.imwrite(photo_name,frame)

                print('create photo is :',photo_name)
            #按鍵盤‘Q’中斷采集
            if key & 0xFF == ord('q'):
                break

if __name__ == '__main__':
    gain_photo(photo_path)
video = cv2.VideoCapture(0)中的0代表的是我的USB相機在我電腦上的驅(qū)動位置
if __name__ == '__main__':就是判斷這些代碼是不是要當(dāng)作單獨的代碼執(zhí)行,如果是就執(zhí)行if中的內(nèi)容,。

標(biāo)定

我先上代碼吧

import cv2
import sys
import numpy as np
import glob

#標(biāo)定圖像保存路徑
photo_path = "C:\\Users\\wlx\\Documents\\py_study\\camera calibration\\image"
#標(biāo)定圖像
def calibration_photo(photo_path):
    #設(shè)置要標(biāo)定的角點個數(shù)
    x_nums = 9                                                          #x方向上的角點個數(shù)
    y_nums = 7
    # 設(shè)置(生成)標(biāo)定圖在世界座標(biāo)中的座標(biāo)
    world_point = np.zeros((x_nums * y_nums,3),np.float32)            #生成x_nums*y_nums個座標(biāo),,每個座標(biāo)包含x,y,z三個元素
    world_point[:,:2] = np.mgrid[:x_nums,:y_nums].T.reshape(-1, 2)    #mgrid[]生成包含兩個二維矩陣的矩陣,每個矩陣都有x_nums列,y_nums行
                                                                        #.T矩陣的轉(zhuǎn)置
                                                                        #reshape()重新規(guī)劃矩陣,,但不改變矩陣元素
    #保存角點座標(biāo)
    world_position = []
    image_position = []
    #設(shè)置角點查找限制
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,30,0.001)
    #獲取所有標(biāo)定圖
    images = glob.glob(photo_path+'\\*.jpg')
    #print(images)
    for image_path in images:
        image = cv2.imread(image_path)
        gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
        #查找角點
        ok,corners = cv2.findChessboardCorners(gray,(y_nums,x_nums),None)

        if ok:
            #把每一幅圖像的世界座標(biāo)放到world_position中
            world_position.append(world_point)
            #獲取更精確的角點位置
            exact_corners = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
            #把獲取的角點座標(biāo)放到image_position中
            image_position.append(exact_corners)
            #可視化角點
            # image = cv2.drawChessboardCorners(image,(y_nums,x_nums),exact_corners,ok)
            # cv2.imshow('image_corner',image)
            # cv2.waitKey(5000)
    #計算內(nèi)外參數(shù)
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(world_position, image_position, gray.shape[::-1], None,None)
    print(mtx, dist)
    #計算偏差
    mean_error = 0
    for i in range(len(world_position)):
        image_position2, _ = cv2.projectPoints(world_position[i], rvecs[i], tvecs[i], mtx, dist)
        error = cv2.norm(image_position[i], image_position2, cv2.NORM_L2) / len(image_position2)
        mean_error += error
    print("total error: ", mean_error / len(image_position))
    
if __name__ == '__main__':
    calibration_photo(photo_path)

使用opencv標(biāo)定這些圖像,,步驟大致就是:

1、設(shè)置想標(biāo)定角點的個數(shù)

2,、創(chuàng)建對應(yīng)角點個數(shù)的世界座標(biāo)

3,、將采集到的標(biāo)定圖讀入緩存

4、灰度處理

5,、使用findChessboardCorners(img,patternSize,corners,flags=None)函數(shù),,查找圖像中的內(nèi)點

  • image:輸入的棋盤圖像,必須是8位的灰度或者彩色圖像
  • patternSize:棋盤中每行每列的角點個數(shù)
  • corners:檢測到的角點
  • flags:各種操作標(biāo)準(zhǔn)

6,、使用cornerSubPix(image,corners,winSize,zeroZone,criteria)函數(shù),,精確查找圖像上的角點

  • image:輸入圖像,,,必須是8位的灰度或者彩色圖像

  • corners:輸入角點的初始化座標(biāo),,也存儲精確的輸出角點座標(biāo)

  • winSize:搜索窗口的一半尺度,如winSize=(5,5),,則使用(2x5+1, 2x5+1)=(11,11)的搜索窗

  • zeroZone:死區(qū)的一半尺寸,,死區(qū)為不對搜索區(qū)做求和運算的區(qū)域,當(dāng)值為(-1,-1)時,,表示沒有死區(qū)

  • criteria:搜索角點停止的標(biāo)志

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,30,0.001)就是一個標(biāo)志,,TERM_CRITERIA_EPS 代表誤差也就是精度,TERM_CRITERIA_MAX_ITER代表迭代次數(shù),,它兩之和就是指兩個因素同時作用,,這里當(dāng)?shù)螖?shù)超過30或誤差大于0.001都會停止運算。

7、將圖像的世界座標(biāo)保存到數(shù)組world_position中,,將找到的角點座標(biāo)保存到數(shù)組image_position中

8,、使用cv2.calibrateCamera(world_position, image_position, gray.shape[::-1], None,None)計算內(nèi)外參數(shù)

9、計算一下準(zhǔn)確度,,也就是通過你算出來的內(nèi)外參數(shù),,逆運算出角點座標(biāo),然后將這個座標(biāo)和識別出來的角點座標(biāo)進行誤差運算,,得到偏差值,。

最后,可以將得到的內(nèi)外參數(shù)保存到一個文件中,,以后在用相機采集圖像時,,就可以用內(nèi)外參數(shù)去矯正圖像了,這里我沒做圖像的矯正,,過幾天做了再也上來,。

另外,用來標(biāo)定的圖像不要太少,,我做了實驗隨著標(biāo)定圖像的增加,,最后計算出的偏差會減小,;而且拍攝標(biāo)定圖像時,,角度要合理,相機固定位置不要發(fā)生變化,。

下面是我實驗,,就是為了驗證代碼是否能運行,所以沒有打印標(biāo)定圖紙,,而是直接用攝像頭拍攝電腦顯示器上的圖像,,攝像頭也沒固定牢靠,所以結(jié)果不是很好,。拍攝了20張圖像

相機內(nèi)參:

[[1.24956824e+03 0.00000000e+00 2.16230694e+02]
 [0.00000000e+00 2.92154313e+03 3.87901459e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]] 

相機外參:

[[-2.80875093e+02  8.92572104e+03 -2.80196846e+00  8.90336346e+00 -1.46134126e+05]]

偏差值:

error:  6.968280883027417

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多