반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

폴크(FOLC)

C# - 머신 비전 알고리즘 - OpenCV - 캘리브레이션 본문

머신 비전/머신 비전 알고리즘 테크닉 C#

C# - 머신 비전 알고리즘 - OpenCV - 캘리브레이션

folcjin 2021. 10. 17. 21:18
728x90
반응형

# 눈으로 보는 실제 공간 3차원 정보(XYZ)를 가상 공간 2차원 정보(XY-이미지)로 표현하는데 필요한 파라미터를 찾는 과정
   # 실제 공간 3차원 정보의 특별한 1Point -> 가상 공간 2차원 정보의 특별한 1Point 로 맵핑된다.
   # 위와 같은 과정중에는 많은 오차들이 존재 ( 사용 렌즈, 렌즈와 센서 사이 거리, 렌즈와 이미지 센서 사이 각 등등...)

# 3차원 정보를 2차원 정보와의 맵핑을 위해 이용되는 파라미터를 크게 2가지로 분리 한다.
   # 카메라 내부 파라미터 : 초점 거리, 주점, 비대칭 계수
      > 상수값 형태로 표현 가능
   # 카메라 외부 파라미터 : 카메라 좌표계, 공간상 좌표계
      > 회전과 평행 이동으로 표현 가능

 

# 이미지 인헨스 - OpenCV 4.5.3 으로 테스트
   # 3차원 정보를 2차원 정보로 투영 시키는 작업
   > srcImage : 입력, dstImage : 결과, dst_size : 결과 크기, offsetX : X 방향 이동, offsetY : Y 방향 이동
   > interpolation : 보간법, borderMode : 이미지끝부분, angle : 기울기(deg), scale : 배율

// 캘리브레이션
int total_image_count = 30;
int chess_board_countX = 9, chess_board_countY = 6;
Size chess_board_size = new Size(chess_board_countX, chess_board_countY);
List<List<Point3d>> ref_points = new List<List<Point3d>>();
List<List<Point2f>> tar_points = new List<List<Point2f>>();
            
for (int i = 0; i < total_image_count; i++)
{
List<Point3d> ref_board_cross_point_corner = new List<Point3d>();
int x = i % chess_board_countX;
int y = i / chess_board_countX;
ref_board_cross_point_corner.Add(new Point3d((double)x * 280.0, (double)y * 28.0, 0.0));

List<Point2f> tar_found_cross_point_corner = new List<Point2f>();
ChessboardFlags flags = ChessboardFlags.AdaptiveThresh | ChessboardFlags.FastCheck | ChessboardFlags.NormalizeImage;
bool success = Cv2.FindChessboardCorners(srcImage, chess_board_size, OutputArray.Create(tar_found_cross_point_corner), flags);
if (success)
{
CriteriaTypes type = CriteriaTypes.Eps | CriteriaTypes.MaxIter;
int maxCount = 30;
double epsilon = 0.001;
TermCriteria criteria = new TermCriteria(type, maxCount, epsilon);
            
Size winSize = new Size(11, 11), zeroZone = new Size(-1, -1);
Cv2.CornerSubPix(srcImage, tar_found_cross_point_corner, winSize, zeroZone, criteria);
Cv2.DrawChessboardCorners(srcImage, chess_board_size, tar_found_cross_point_corner, success);
}

ref_points.Add(ref_board_cross_point_corner);
tar_points.Add(tar_found_cross_point_corner);
}

Mat camera_instric_matrix = new Mat(), distortion_coeffs = new Mat();
Mat[] rotation_vecs, translate_vecs;
Cv2.CalibrateCamera(ref_points as IEnumerable<Mat>, tar_points as IEnumerable<Mat>, srcImage.Size(), camera_instric_matrix, distortion_coeffs, out rotation_vecs, out translate_vecs);
            
Mat map1 = new Mat(), map2 = new Mat();
Rect outRect = new Rect(0, 0, 0, 0);
Mat new_camera_matrix = Cv2.GetOptimalNewCameraMatrix(camera_instric_matrix, distortion_coeffs, srcImage.Size(), 1.0, srcImage.Size(), out outRect, false);
Cv2.InitUndistortRectifyMap(camera_instric_matrix, distortion_coeffs, new Mat(), new_camera_matrix, srcImage.Size(), MatType.CV_16SC2, map1, map2);
            
보정한다.
if ((map1.Data != null) && (map2.Data != null))
{
Cv2.Remap(srcImage, dstImage, map1, map2, InterpolationFlags.Linear);
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --