일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Barcode
- SERIAL
- mfc
- file access
- aduino
- java
- compare
- Read
- Class
- Contour
- UNO
- APP
- Pointer
- wpf
- Encapusulation
- parameter
- memory
- atmega328
- Unity
- Android
- length
- inheritance
- flutter
- Binary
- stream
- sensor
- digitalRead
- Overloading
- preprocessing
- public
- Today
- Total
폴크(FOLC)
C# - 머신 비전 알고리즘 - OpenCV - 캘리브레이션 본문
# 눈으로 보는 실제 공간 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);
}
'머신 비전 > 머신 비전 알고리즘 테크닉 C#' 카테고리의 다른 글
C# - 머신 비전 알고리즘 - OpenCV - 이미지처리5 (0) | 2021.10.17 |
---|---|
C# - 머신 비전 알고리즘 - OpenCV - 이미지처리4 (0) | 2021.10.17 |
C# - 머신 비전 알고리즘 - OpenCV - 이미지처리3 (0) | 2021.10.17 |
C# - 머신 비전 알고리즘 - OpenCV - 이미지처리2 (0) | 2021.10.16 |
C# - 머신 비전 알고리즘 - OpenCV - 이미지처리1 (0) | 2021.10.15 |