像素精度計算
像素精度——一像素對應多少毫米——距離不同像素精度也不同
將棋盤格與相機CCD平面大致平行擺放,通過【每個點處的近似像素精度=相鄰兩個角點之間的實際距離(棋盤格尺寸已知)/ 棋盤格上檢出的相鄰兩個角點之間的像素距離】,兩兩角點之間計算像素精度,最后取平均
示例:一張1280*1024像素的圖片里,其中的棋盤格是6*9,物理尺寸為12mm*12mm

#include"opencv2/opencv.hpp" using namespace cv; int main() { Mat srcimg = imread("6.bmp"); Mat gray; cvtColor(srcimg,gray,CV_RGB2GRAY); Size board_sz = Size(6,9); vector<Point2f>corners; bool found = findChessboardCorners(srcimg, board_sz, corners,CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS); printf("檢測到的原始角點坐標"); for (size_t i = 0; i < corners.size(); i++) { printf("第%d個點(%f,%f)\n",i,corners[i].x,corners[i].y); } if (found) { printf("成功檢測到角點\n"); //檢測的角點時以右下角為原點的 cornerSubPix(gray,corners,Size(11,11),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1));//輸入的圖像,必須是8位的灰度或者彩色圖像。 drawChessboardCorners(srcimg,board_sz,corners,found); Mat dstimg; resize(srcimg,dstimg,Size(1000,800)); imshow("亞像素角點圖", dstimg); waitKey(20); printf("檢測到的0.1亞像素斜的圖像角點坐標\n"); float jingdux = 0, jinduy = 0; int j = 0; bool flag = false; for (size_t i = 0; i < corners.size(); i++) { if (i==0) { } else { jingdux=sqrt((corners[i].x - corners[i - 1].x)*(corners[i].x - corners[i - 1].x) + (corners[i].y - corners[i - 1].y)*(corners[i].y - corners[i - 1].y)); jingdux = 12.0 / jingdux; } printf("第%d個點(%f,%f)\n", i, corners[i].x, corners[i].y); printf("其像素精度為:%f/像素\n", jingdux); } } waitKey(0); return 0; }

由此可以得到其相機的像素精度是0.17mm/像素(其是相機在某個固定高度上時得出的,相機離目標面越遠,則這個值越大,即精度降低了),其后面的幾位都一直改變,是因為相機標定板也可能傾斜,或者像素長度計算誤差。
物理精度計算
只考慮像素精度是沒有意義的,因為很多相機可以檢測亞像素
像素精度0.17mm/像素,0.1亞像素精度,則其實際定位的物理精度為0.017mm。
這是理想狀況下的,一般還有很多外部影響導致誤差增大,如果考慮外部因素的話定位精度會比理想的多幾倍。
我們的物理精度到了0.017mm,也不代表我們能檢測0.017mm的物體,因為1個亞像素往往凸顯不出特征
誤差處理
如果是通過物體所占的像素多少來計算其長度時,則會出現像素的誤差積累,因為我們是拿一個固定值來與像素相乘的。例如某個尺子長度在此高度的相機里拍到的圖像里所占的像素為100像素,則實際的0.17mm的誤差會累計,假如其誤差是0.01mm,其是固定誤差,即實際的是0.16mm,其固定誤差就會累計成100*0.01mm=1mm的誤差。
現實中有些東西是不會成線性增加,是因為這些誤差是隨機誤差,不是固定誤差,隨機誤差積分時誤差之間會進行抵消。改進方法是要使用很密的棋盤格來對應圖像里的像素點,從而來提高精度,即定位物體的頭跟尾的像素位置,然后把其轉換到以標定紙為坐標系的物理坐標,然后進行相減則可以得出其高精度長度,不會有累計誤差。
