OpenCV 筆記 6 棋盤格校正(class版) - 找到棋盤格位置

背景知識:

OpenCV 筆記 1 安裝配置 與 Camera測試

DLL檔案 的隨手筆記 1 - DLL 4 在DLL中加入 Class範例

DLL檔案 的隨手筆記 1 - DLL 4.1 在DLL中的 C++ static Vector<>類型的要 定義在 Class外面

PS: 提示一點 Mat操做不好的話不要放在Class裏面

將棋盤格的計算放在Class在讀近來

DLL的部分:

UndistortLibrary.h

#pragma once
#include <opencv2/opencv.hpp>
#ifdef UNDISTORTLIBRARY_EXPORTS
#define UNDISTORTLIBRARY_API __declspec(dllexport)
#else
#define UNDISTORTLIBRARY_API __declspec(dllimport)
#endif


class UNDISTORTLIBRARY_API Undistort_CameraLenses {
public:

	Undistort_CameraLenses();
	Undistort_CameraLenses(int i, int j);
	Undistort_CameraLenses(int i, int j, std::string tmp_Path, std::string tmp_type = "*.jpg");

	std::string Version();
	void Image_Paths_Collect(std::string tmp_Path, std::string tmp_type="*.jpg");
	int Image_Paths_size();

	void Obj_world_init();
	
	void ChessBoard_Size_set(int i, int j);
	int ChessBoard_Size_get(int i);
	cv::Mat Find_Chessboard_Corners(int i);

private:
	
	int ChessBoard_Size0 = 6;
	int ChessBoard_Size1 = 9;
	

};

std::vector<std::string> Undistort_images_path;
std::vector<cv::Point3f> Undistort_obj_world_pts;
std::vector<cv::Point2f> Undistort_img_corner_points;
std::vector<std::vector<cv::Point3f>> Undistort_objpoints_img;
std::vector<std::vector<cv::Point2f>> Undistort_images_points;

 

UndistortLibrary.cpp

#include "pch.h" 
#include <utility>
#include <limits.h>
#include <vector>
#include <string>
#include "opencv2\imgproc\types_c.h"
#include "opencv2\opencv.hpp"
#include "UndistortLibrary.h"



Undistort_CameraLenses::Undistort_CameraLenses()
{
	
}

Undistort_CameraLenses::Undistort_CameraLenses(int i, int j)
{
	ChessBoard_Size0 = i;
	ChessBoard_Size1 = j;

	Undistort_objpoints_img.clear();
	Undistort_images_points.clear();
	Undistort_obj_world_pts.clear();
	Undistort_img_corner_points.clear();

	for (int i = 0; i < ChessBoard_Size1; i++)
	{
		for (int j = 0; j < ChessBoard_Size0; j++)
		{
			Undistort_obj_world_pts.push_back(cv::Point3f(j, i, 0));
		}
	}

}

Undistort_CameraLenses::Undistort_CameraLenses(int i, int j, std::string tmp_Path, std::string tmp_type)
{
	ChessBoard_Size0 = i;
	ChessBoard_Size1 = j;

	Undistort_objpoints_img.clear();
	Undistort_images_points.clear();
	Undistort_obj_world_pts.clear();
	Undistort_img_corner_points.clear();

	for (int i = 0; i < ChessBoard_Size1; i++)
	{
		for (int j = 0; j < ChessBoard_Size0; j++)
		{
			Undistort_obj_world_pts.push_back(cv::Point3f(j, i, 0));
		}
	}

	Undistort_images_path.clear();
	cv::glob(tmp_Path + "//" + tmp_type, Undistort_images_path);


}


std::string Undistort_CameraLenses::Version()
{

	return "Version 2025/01/15 \n";
}

void Undistort_CameraLenses::Image_Paths_Collect(std::string tmp_Path, std::string tmp_type)
{
	Undistort_images_path.clear();
	cv::glob(tmp_Path + "//" + tmp_type, Undistort_images_path);
	// return Undistort_images_path;
}

int Undistort_CameraLenses::ChessBoard_Size_get(int i)
{
	if(i == 0) 
		return ChessBoard_Size0;
	else 
		return ChessBoard_Size1;
	
}

void Undistort_CameraLenses::ChessBoard_Size_set(int i, int j)
{
	ChessBoard_Size0 = i;
	ChessBoard_Size1 = j;
}


void Undistort_CameraLenses::Obj_world_init()
{
	Undistort_objpoints_img.clear();
	Undistort_images_points.clear();
	Undistort_obj_world_pts.clear();
	Undistort_img_corner_points.clear();

	for (int i = 0; i < ChessBoard_Size1; i++)
	{
		for (int j = 0; j < ChessBoard_Size0; j++)
		{
			Undistort_obj_world_pts.push_back(cv::Point3f(j, i, 0));
		}
	}

}

int Undistort_CameraLenses::Image_Paths_size()
{
	return Undistort_images_path.size();
}


cv::Mat Undistort_CameraLenses::Find_Chessboard_Corners(int i )
{
	cv::Mat Undistort_image = cv::imread(Undistort_images_path[i]);
	cv::Mat Undistort_img_gray;
	cvtColor(Undistort_image, Undistort_img_gray, cv::COLOR_BGR2GRAY);
	
	bool found_success = findChessboardCorners(
		Undistort_img_gray, 
		cv::Size(ChessBoard_Size0, ChessBoard_Size1),
		Undistort_img_corner_points, 
		cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);


	if (found_success)
	{
		
		cv::TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.001);

		
		cornerSubPix(Undistort_img_gray, 
			Undistort_img_corner_points, 
			cv::Size(11, 11), cv::Size(-1, -1), criteria);

		
		drawChessboardCorners(
			Undistort_image, 
			cv::Size(ChessBoard_Size0, ChessBoard_Size1),
			Undistort_img_corner_points, found_success);

		Undistort_objpoints_img.push_back(Undistort_obj_world_pts);
		Undistort_images_points.push_back(Undistort_img_corner_points);


	}
	else 
	{
		std::cout << "XXX";
	}


	return Undistort_image;
}

 

執行檔部分

source.cpp

#include <iostream>
#include "opencv2\imgproc\types_c.h"
#include "opencv2/opencv.hpp"
#include "UndistortLibrary.h"


using namespace cv;
using namespace std;




int main()
{
	Undistort_CameraLenses Undis_test;

	Undis_test.Obj_world_init();
	Undis_test.ChessBoard_Size_set(6,9);
	Undis_test.Image_Paths_Collect("./ChessboardCorner/ChessboardCorner","*.jpg");

	cout << Undis_test.Image_Paths_size();

	for (int i = 0; i < Undis_test.Image_Paths_size(); i++)
	{
		imshow("image", Undis_test.Find_Chessboard_Corners(i));
		waitKey(200);
	}

	destroyAllWindows();
	system("pause");
	return 0;
}

 

在OPENCV的github可以找到圖片

https://github.com/opencv/opencv
opencv-4.x\samples\data