OpenCV Tutorial 10 - Chapter 11

 ( 由于收到附件大小的限制,此篇的图片无法上传,请大家见谅,可登陆原网站查看:http://dasl.mem.drexel.edu/~noahKuntz/openCVTut10.html)

Author: Noah Kuntz (2009)
Contact: nk752@drexel.edu

Keywords: OpenCV, computer vision, calibration, camera parameters

My Vision Tutorials Index

This tutorial assumes the reader:
(1) Has a basic knowledge of Visual C++
(2) Has some familiarity with computer vision concepts
(3) Has read the previous tutorials in this series

The rest of the tutorial is presented as follows:

Important Note!

More information on the topics of these tutorials can be found in this book:Learning OpenCV: Computer Vision with the OpenCV Library

Step 1: Camera Calibration(摄像机标定)


Corner Finding for Calibration(找到用于校准的角点)

 


Image Undistortion After Calibration(校准后的图像Undistortion)


Camera calibration is important for any image processing to be a highly accurate representation of the real world(摄像机标定对于任何图像处理都是非常重要的,是对现实世界的高度准确地表述). The basics of perspective geometry are covered in the book(在书中,涵盖了透视几何的基础知识). The concern of this tutorial is simply how to extract the relevant camera parameters from a sequence of images(本教程的关注仅仅是如何从一个摄像机图像序列中提取相关的参数). For this example you will need to print out this image as a full page(在这个例子中,你将需要将这个图片作为一整页打印出):


Example Checkerboard(棋盘法)


This code uses cvFindChessboardCorners to find the corners, and then draw them on the current image withcvDrawChessboardCorners(此代码使用cvFindChessboardCorners来找到角点,然后用cvDrawChessboardCorners把它们绘制在当前的图像上). If all the corners are successfully identified, the corners are added to image_points and object_points for later use in calibration(如果所有的角点都成功地确定,则角点被添加到image_points和object_points上为日后的校准使用). After all the different orientations are successfully stored (orientations are arbitrary but should have a variety of views to solve for the camera parameters), thencvCalibrateCamera2 is used to get the camera parameters(毕竟不同的方向被成功地存储(方向是任意的,但是应该有不同观点去解决摄像机的参数),然后用cvCalibrateCamera2来获取摄像机参数). Lastly,cvInitUndistoryMap is used with cvRemap to unwarp the camera images(最后,cvInitUndistoryMap是用于cvRemap到unwarp相机的图像). So for the user, simply print out the checkerboard, then point the camera at it in various orientations as the program marks the points in each one (it is successful if a variety of colors are used, all red or nothing is a failure)(因此,对于用户来说,只需打印出棋盘,然后对准它在各个方向相机,该方案标志着在每一个点(它是成功的,如果有多种颜色的使用,全是红色或没有东西则是失败的)). The intrinsics of the camera and the distortion are stored in xml files to use in other programs(摄像机的内建和失真被存储在XML文件中以便其他程序的使用). Here is the code(以下是代码):


 

int n_boards = 0;

const int board_dt = 20;

int board_w;

int board_h;

 

int _tmain(int argc, _TCHAR* argv[])

{

        board_w = 5; // Board width in squares

        board_h = 8; // Board height

        n_boards = 8; // Number of boards

        int board_n = board_w * board_h;

        CvSize board_sz = cvSize( board_w, board_h );

        CvCapture* capture = cvCreateCameraCapture( 0 );

        assert( capture );

 

        cvNamedWindow( "Calibration" );

        // Allocate Sotrage

        CvMat* image_points            = cvCreateMat( n_boards*board_n, 2, CV_32FC1 );

        CvMat* object_points           = cvCreateMat( n_boards*board_n, 3, CV_32FC1 );

        CvMat* point_counts                   = cvCreateMat( n_boards, 1, CV_32SC1 );

        CvMat* intrinsic_matrix               = cvCreateMat( 3, 3, CV_32FC1 );

        CvMat* distortion_coeffs       = cvCreateMat( 5, 1, CV_32FC1 );

 

        CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];

        int corner_count;

        int successes = 0;

        int step, frame = 0;

 

        IplImage *image = cvQueryFrame( capture );

        IplImage *gray_image = cvCreateImage( cvGetSize( image ), 8, 1 );

 

        // Capture Corner views loop until we've got n_boards

        // succesful captures (all corners on the board are found)

 

        while( successes < n_boards ){

               // Skp every board_dt frames to allow user to move chessboard

               if( frame++ % board_dt == 0 ){

                       // Find chessboard corners:

                       int found = cvFindChessboardCorners( image, board_sz, corners,

                               &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS );

 

                       // Get subpixel accuracy on those corners

                       cvCvtColor( image, gray_image, CV_BGR2GRAY );

                       cvFindCornerSubPix( gray_image, corners, corner_count, cvSize( 11, 11 ),

                               cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

 

                       // Draw it

                       cvDrawChessboardCorners( image, board_sz, corners, corner_count, found );

                       cvShowImage( "Calibration", image );

 

                       // If we got a good board, add it to our data

                       if( corner_count == board_n ){

                               step = successes*board_n;

                               for( int i=step, j=0; j < board_n; ++i, ++j ){

                                      CV_MAT_ELEM( *image_points, float, i, 0 ) = corners[j].x;

                                      CV_MAT_ELEM( *image_points, float, i, 1 ) = corners[j].y;

                                      CV_MAT_ELEM( *object_points, float, i, 0 ) = j/board_w;

                                      CV_MAT_ELEM( *object_points, float, i, 1 ) = j%board_w;

                                      CV_MAT_ELEM( *object_points, float, i, 2 ) = 0.0f;

                               }

                               CV_MAT_ELEM( *point_counts, int, successes, 0 ) = board_n;

                               successes++;

                       }

               }

 

               // Handle pause/unpause and ESC

               int c = cvWaitKey( 15 );

               if( c == 'p' ){

                       c = 0;

                       while( c != 'p' && c != 27 ){

                               c = cvWaitKey( 250 );

                       }

               }

               if( c == 27 )

                       return 0;

               image = cvQueryFrame( capture ); // Get next image

        } // End collection while loop

 

        // Allocate matrices according to how many chessboards found

        CvMat* object_points2 = cvCreateMat( successes*board_n, 3, CV_32FC1 );

        CvMat* image_points2 = cvCreateMat( successes*board_n, 2, CV_32FC1 );

        CvMat* point_counts2 = cvCreateMat( successes, 1, CV_32SC1 );

       

        // Transfer the points into the correct size matrices

        for( int i = 0; i < successes*board_n; ++i ){

               CV_MAT_ELEM( *image_points2, float, i, 0) = CV_MAT_ELEM( *image_points, float, i, 0 );

               CV_MAT_ELEM( *image_points2, float, i, 1) = CV_MAT_ELEM( *image_points, float, i, 1 );

               CV_MAT_ELEM( *object_points2, float, i, 0) = CV_MAT_ELEM( *object_points, float, i, 0 );

               CV_MAT_ELEM( *object_points2, float, i, 1) = CV_MAT_ELEM( *object_points, float, i, 1 );

               CV_MAT_ELEM( *object_points2, float, i, 2) = CV_MAT_ELEM( *object_points, float, i, 2 );

        }

 

        for( int i=0; i < successes; ++i ){

               CV_MAT_ELEM( *point_counts2, int, i, 0 ) = CV_MAT_ELEM( *point_counts, int, i, 0 );

        }

        cvReleaseMat( &object_points );

        cvReleaseMat( &image_points );

        cvReleaseMat( &point_counts );

 

        // At this point we have all the chessboard corners we need

        // Initiliazie the intrinsic matrix such that the two focal lengths

        // have a ratio of 1.0

 

        CV_MAT_ELEM( *intrinsic_matrix, float, 0, 0 ) = 1.0;

        CV_MAT_ELEM( *intrinsic_matrix, float, 1, 1 ) = 1.0;

 

        // Calibrate the camera

        cvCalibrateCamera2( object_points2, image_points2, point_counts2, cvGetSize( image ),

               intrinsic_matrix, distortion_coeffs, NULL, NULL, CV_CALIB_FIX_ASPECT_RATIO );

 

        // Save the intrinsics and distortions

        cvSave( "Intrinsics.xml", intrinsic_matrix );

        cvSave( "Distortion.xml", distortion_coeffs );

 

        // Example of loading these matrices back in

        CvMat *intrinsic = (CvMat*)cvLoad( "Intrinsics.xml" );

        CvMat *distortion = (CvMat*)cvLoad( "Distortion.xml" );

 

        // Build the undistort map that we will use for all subsequent frames

        IplImage* mapx = cvCreateImage( cvGetSize( image ), IPL_DEPTH_32F, 1 );

        IplImage* mapy = cvCreateImage( cvGetSize( image ), IPL_DEPTH_32F, 1 );

        cvInitUndistortMap( intrinsic, distortion, mapx, mapy );

 

        // Run the camera to the screen, now showing the raw and undistorted image

        cvNamedWindow( "Undistort" );

 

        while( image ){

               IplImage *t = cvCloneImage( image );

               cvShowImage( "Calibration", image ); // Show raw image

               cvRemap( t, image, mapx, mapy ); // undistort image

               cvReleaseImage( &t );

               cvShowImage( "Undistort", image ); // Show corrected image

 

               // Handle pause/unpause and esc

               int c = cvWaitKey( 15 );

               if( c == 'p' ){

                       c = 0;

                       while( c != 'p' && c != 27 ){

                               c = cvWaitKey( 250 );

                       }

               }

               if( c == 27 )

                       break;

               image = cvQueryFrame( capture );

        }

 

        return 0;

}

 


 

Final Words(结束语)

This tutorial's objective was to show how to extract camera parameters using calibration routines(本教程的目标是展示如何提取摄像机参数来校准程序).

Click here to email me.
Click here to return to my Tutorials page.

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值