天天看点

用opencv计算棋盘格内角点坐标(通过4个内角点获得转换矩阵),并同时用halcon和opnecv对图像进行透视变换

该篇和上篇的主要区别是选取4个内角点而不是全部内角点计算转换矩阵,程序改变不大,主要是想看一下两者之间矫正结果有什么区别。

// projectivetest.cpp : 定义控制台应用程序的入口点。
//通过四点获得透视变换矩阵

#include "stdafx.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <stdlib.h>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <fstream>
#include "halconcpp.h"
using namespace HalconCpp;
using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	HTuple originalcornersX,originalcornersY,leancornersX,leancornersY;//halcon中用于保存角点变量
	ofstream oFileExcel1;
	ofstream oFileExcel2;
	string strExcel1="垂直角点.csv";
	oFileExcel1.open(strExcel1.c_str(), ios::out | ios::trunc);//保存垂直拍摄靶标的角点
	string strExcel2="倾斜拍摄.csv";
	oFileExcel2.open(strExcel2.c_str(), ios::out | ios::trunc);//保存倾斜拍摄靶标的角点

	cv::Mat  calibmat[2];//两个存储图像
	std::vector<cv::Point2f> pointscz,pointsqx;//角点
	std::vector<cv::Point2f> pointscz4(4),pointsqx4(4);//四个边缘角点
	int width ,height;//图像长宽

	 calibmat[0]=imread("C:\\Users\\Administrator\\Desktop\\7_7自定义标定板2\\cz16cm0.bmp",4);//读取垂直标定图像
	 calibmat[1]=imread("C:\\Users\\Administrator\\Desktop\\7_7自定义标定板2\\x30_0.bmp",4);//读取倾斜标定图像

	width=calibmat[0].cols;
	height=calibmat[1].rows;
	bool iffindpointcz,iffindpointqx;

	//计算垂直拍摄标定板的内角点坐标
	iffindpointcz=findChessboardCorners(calibmat[0],cv::Size(9,7),pointscz,CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
	if(iffindpointcz)
	{
		//cornerSubPix(calibmat[0],points,cv::Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER,40,0.001 ));
		if(iffindpointcz)//亚像素提取
		{
			drawChessboardCorners(calibmat[0],cv::Size(9,7),pointscz,true); //用于在图片中标记角点 
            imwrite("垂直角点图.bmp",calibmat[0]);//保存角点图
			//四个角点保存
               originalcornersX[0]=pointscz[0].x;//保存角点信息到halcon变量中方便计算仿射变换
			   originalcornersY[0]=pointscz[0].y;
			   originalcornersX[1]=pointscz[8].x;//保存角点信息到halcon变量中方便计算仿射变换
			   originalcornersY[1]=pointscz[8].y;
			   originalcornersX[2]=pointscz[54].x;//保存角点信息到halcon变量中方便计算仿射变换
			   originalcornersY[2]=pointscz[54].y;
			   originalcornersX[3]=pointscz[62].x;//保存角点信息到halcon变量中方便计算仿射变换
			   originalcornersY[3]=pointscz[62].y;

			   pointscz4[0].x=pointscz[0].x;//保存角点信息到halcon变量中方便计算仿射变换
			   pointscz4[0].y=pointscz[0].y;
			   pointscz4[1].x=pointscz[8].x;//保存角点信息到halcon变量中方便计算仿射变换
			   pointscz4[1].y=pointscz[8].y;
			   pointscz4[2].x=pointscz[54].x;//保存角点信息到halcon变量中方便计算仿射变换
			   pointscz4[2].y=pointscz[54].y;
			   pointscz4[3].x=pointscz[62].x;//保存角点信息到halcon变量中方便计算仿射变换
			   pointscz4[3].y=pointscz[62].y;

			for(int i=0;i<pointscz.size();i++)
		   {
			   
			   oFileExcel1<<"[x:y]"<<","<<pointscz[i].x<<","<<pointscz[i].y<<",";//输出内角点坐标到excel
			   if ((i+1)%7==0)
			   {
				   oFileExcel1<<endl;
			   }
		    }
            oFileExcel1.close();
		}		
	}

	//计算倾斜拍摄标定板的内角点坐标
	iffindpointqx=findChessboardCorners(calibmat[1],cv::Size(9,7),pointsqx,CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
	if(iffindpointqx)
	{
	     //cornerSubPix(calibmat[1],points,cv::Size(5,5),Size(-1,-1),TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER,40,0.001 ));
		if(iffindpointqx)
		{
                leancornersX[0]=pointsqx[0].x;//保存角点信息到halcon变量中方便计算仿射变换
				leancornersY[0]=pointsqx[0].y;
				leancornersX[1]=pointsqx[8].x;//保存角点信息到halcon变量中方便计算仿射变换
				leancornersY[1]=pointsqx[8].y;
				leancornersX[2]=pointsqx[54].x;//保存角点信息到halcon变量中方便计算仿射变换
				leancornersY[2]=pointsqx[54].y;
				leancornersX[3]=pointsqx[62].x;//保存角点信息到halcon变量中方便计算仿射变换
				leancornersY[3]=pointsqx[62].y;

				pointsqx4[0].x=pointsqx[0].x;//保存角点信息到halcon变量中方便计算仿射变换
				pointsqx4[0].y=pointsqx[0].y;
				pointsqx4[1].x=pointsqx[8].x;//保存角点信息到halcon变量中方便计算仿射变换
				pointsqx4[1].y=pointsqx[8].y;
				pointsqx4[2].x=pointsqx[54].x;//保存角点信息到halcon变量中方便计算仿射变换
				pointsqx4[2].y=pointsqx[54].y;
				pointsqx4[3].x=pointsqx[62].x;//保存角点信息到halcon变量中方便计算仿射变换
				pointsqx4[3].y=pointsqx[62].y;


			for(int i=0;i<pointsqx.size();i++)
			{
				
				oFileExcel2<<"[x:y]"<<","<<pointsqx[i].x<<","<<pointsqx[i].y<<",";//输出内角点坐标到excel
				if ((i+1)%7==0)
				{
					oFileExcel2<<endl;
				}
			}
			drawChessboardCorners(calibmat[1],cv::Size(9,7),pointsqx,true); //用于在图片中标记角点 
			imwrite("棋盘倾斜角点.bmp",calibmat[1]);
			oFileExcel2.close();
		}
		
	}
	HTuple ones,HomMat2D;
	HObject originimg,projimg;//保存用于矫正前后的图
	ones=HTuple(4,1);
	Mat math,mask,origimg,desimg;
	if(iffindpointqx&&iffindpointcz)
	{
		//######用opencv对图像进行矫正######################################################################
		//findHomography 函数是求两幅图像的变换矩阵
		math=cv::findHomography(pointsqx4,pointscz4,mask);
		origimg=imread("C:\\Users\\Administrator\\Desktop\\7_7自定义标定板2\\y30_0.bmp",4);//读取垂直标定图像
		//主要作用:opencv对图像进行透视变换,就是变形
		cv::warpPerspective(origimg,desimg,math,Size(origimg.cols,origimg.rows));
		imwrite("7opencv矫正4点30.bmp",desimg);

		//#######用halcon对图像进行矫正#####################################################################
		//求两幅图像的变换矩阵
        HomVectorToProjHomMat2d(leancornersY,leancornersX,ones,originalcornersY,originalcornersX,ones,"normalized_dlt",&HomMat2D);
		ReadImage(&originimg,"C:/Users/Administrator/Desktop/7_7自定义标定板2/y30_0.bmp");
		//主要作用:halcon对图像进行透视变换,就是变形
		ProjectiveTransImage(originimg,&projimg,HomMat2D,"bilinear","false","false");
		WriteImage(projimg,"bmp",0,"7halcon矫正图4点30.bmp");
	}	
	return 0;
}
           

欢迎扫码关注我的微信公众号

用opencv计算棋盘格内角点坐标(通过4个内角点获得转换矩阵),并同时用halcon和opnecv对图像进行透视变换