https://blog.csdn.net/u010128736/article/details/52875137

https://blog.csdn.net/h532600610/article/details/51800488

python 角点检测+相机标定+去畸变+重投影误差计算:

#coding:utf-8
import cv2
import numpy as np
import glob # 找棋盘格角点
# 阈值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#棋盘格模板规格
w = 9
h = 6
# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点 images = glob.glob('calib/*.png')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 找到棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
# 如果找到足够点对,将其存储起来
if ret == True:
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
objpoints.append(objp)
imgpoints.append(corners)
# 将角点在图像上显示
cv2.drawChessboardCorners(img, (w,h), corners, ret)
cv2.imshow('findCorners',img)
cv2.waitKey(1)
cv2.destroyAllWindows() # 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 去畸变
img2 = cv2.imread('calib/00169.png')
h, w = img2.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例参数
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# 根据前面ROI区域裁剪图片
#x,y,w,h = roi
#dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst) # 反投影误差
total_error = 0
for i in xrange(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
total_error += error
print "total error: ", total_error/len(objpoints)

标定 cv2.calibrateCamera函数文档:https://docs.opencv.org/2.4.1/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

c++ 角点检测+角点绘制:

#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std; int main( )
{
cout<<"Draw Chess OpenCV!"<<endl;
char* filename="..//image5.jpg";
char* filename2="..//5.jpg";
IplImage* imgRGB = cvLoadImage(filename);
IplImage* imgGrey = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); if (imgGrey==NULL){//image validation
cout<< "No valid image input."<<endl;
char c=getchar();
return ;
} //-------find chessboard corners--------------
int corner_row=;//interior number of row corners.(this can be countered by fingers.)
int corner_col=;//interior number of column corners.
int corner_n=corner_row*corner_col;
CvSize pattern_size=cvSize(corner_row,corner_col);
// CvPoint2D32f* corners=new CvPoint2D32f[corner_n];
CvPoint2D32f corners[];
int corner_count; int found=cvFindChessboardCorners(//returning non-zero means sucess.
imgGrey,// 8-bit single channel greyscale image.
pattern_size,//how many INTERIOR corners in each row and column of the chessboard.
corners,//an array where the corner locations can be recorded.
&corner_count,// optional, if non-NULL, its a point to an integer where the nuber of corners found can be recorded.
// CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS// check page 382-383. );
cout<<"corner_count = "<<corner_count;
//-------Draw the corner pattern-------
cvDrawChessboardCorners(
imgRGB,
pattern_size,
corners,
corner_count,
found
);
cvSaveImage(filename2,imgRGB);
//to summary a bit of findings.
cout<<"found="<<found<<endl;
cout<<"x="<<corners[].x;
cout<<",y="<<corners[].y<<endl; cvNamedWindow("Find and Draw ChessBoard", );
cvShowImage( "Find and Draw ChessBoard", imgRGB ); cvWaitKey(); cvReleaseImage(&imgGrey);
cvReleaseImage(&imgRGB);
cvDestroyWindow("Find and Draw ChessBoard"); return ;
}

注意事项:

  • pattern_size参数传递内点数,8*8的棋盘只有7*7内点。
  • 图像选取应注意减少干扰,例如光照与背景等。
  • Corners中的角点坐标顺序排列规律不一定是以行从左上到右下。使用坐标计算映射关系时应提高警惕,对坐标进行重新排列。

关键函数参数说明:

int cvFindChessboardCorners( const void* image, CvSize pattern_size, CvPoint2D32f* corners, int* corner_count=NULL, int flags=CV_CALIB_CB_ADAPTIVE_THRESH );

Image:

输入的棋盘图,必须是8位的灰度或者彩色图像。

pattern_size:

棋盘图中每行和每列角点的个数。

Corners:

检测到的角点

corner_count:

输出,角点的个数。如果不是NULL,函数将检测到的角点的个数存储于此变量。

Flags:

各种操作标志,可以是0或者下面值的组合:

CV_CALIB_CB_ADAPTIVE_THRESH -使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。

CV_CALIB_CB_NORMALIZE_IMAGE -在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。

CV_CALIB_CB_FILTER_QUADS -使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

opencv 角点检测+相机标定+去畸变+重投影误差计算的更多相关文章

  1. 【opencv】projectPoints 三维点到二维点 重投影误差计算

    今天计算rt计算误差——重投影误差 用solvepnp或sovlepnpRansac,输入3d点.2d点.相机内参.相机畸变,输出r.t之后 用projectPoints,输入3d点.相机内参.相机畸 ...

  2. OpenCV角点检测源代码分析(Harris和ShiTomasi角点)

    OpenCV中常用的角点检测为Harris角点和ShiTomasi角点. 以OpenCV源代码文件 .\opencv\sources\samples\cpp\tutorial_code\Trackin ...

  3. OpenCV角点检测goodFeaturesToTrack()源代码分析

    上面一篇博客分析了HARRIS和ShiTomasi角点检测的源代码.而为了提取更准确的角点,OpenCV中提供了goodFeaturesToTrack()这个API函数,来获取更加准确的角点位置.这篇 ...

  4. opencv: 角点检测源码分析;

    以下6个函数是opencv有关角点检测的函数 ConerHarris, cornoerMinEigenVal,CornorEigenValsAndVecs, preConerDetect, coner ...

  5. Opencv 张正友相机标定傻瓜教程

    注: 程序所用的OpenCV版本是 2.4.10 ,3.0以上的版本可能会有不同 先贴一下完整的工程代码: #include "opencv2/core/core.hpp" #in ...

  6. Opencv角点检测

    #include "stdafx.h" #define max_corners 20 int main() { int cornerNum = max_corners; vecto ...

  7. 相机标定过程(opencv) + matlab参数导入opencv + matlab标定和矫正

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...

  8. OpenCV相机标定和姿态更新

    原帖地址: http://blog.csdn.net/aptx704610875/article/details/48914043 http://blog.csdn.net/aptx704610875 ...

  9. 使用OpenCV进行相机标定

    1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...

随机推荐

  1. jquery ajaxSubmit

    <script type="text/javascript" src="jquery/jquery.js"></script></ ...

  2. 架构设计之Spring-Session的分布式集群会话管理

    发表于 2017-04-24  |  160次围观   |   分类于 架构设计   |   暂无评论 前言 通常在web开发中,回话管理是很重要的一部分,用于存储与用户相关的一些数据.对于JAVA开 ...

  3. JSF request参数传递

    转载自:http://blog.csdn.net/duankaige/article/details/6711044 1:JSF页面之间传参 方法1: <h:outputLink value=& ...

  4. LT和ET模式

    #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include &l ...

  5. 如何对MySQL中的大表进行数据归档

    使用MySQL的过程,经常会遇到一个问题,比如说某张”log”表,用于保存某种记录,随着时间的不断的累积数据,但是只有最新的一段时间的数据是有用的:这个时候会遇到性能和容量的瓶颈,需要将表中的历史数据 ...

  6. 实例具体解释Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)

    这是本系列的第二篇,内容是 prefetch_related() 函数的用途.实现途径.以及用法. 本系列的第一篇在这里 第三篇在这里 3. prefetch_related() 对于多对多字段(Ma ...

  7. 考虑下面两个JSP文件代码片断: test1.jsp:

    <HTML> <BODY> <% pageContext.setAttribute(”ten”,new Integer(10));%> //1 </BODY& ...

  8. IIS故障问题(Connections_Refused)分析及处理【转】

    这篇文章其实已经写好很久,只是后来一直没有重现当时的问题,或者因为业务的重要性.投诉的压力也就临时处理了.这几天某地市Web服务器连续多次出现这个问题,正好借这个案例来做个收尾. 前几个月有台重要的W ...

  9. springcloud微服务架构搭建

    SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...

  10. Thinkphp新增字段无法插入到数据库问题

    Thinkphp框架开发过程中,因需求需要改动数据表,新增了几个字段. 调用 M(‘xxx’)->add($data) 插入值时,新增的字段数据总是插入不进去,每次都是默认的值,于是恍然—-缓存 ...