일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- aduino
- sensor
- compare
- Pointer
- SERIAL
- Encapusulation
- inheritance
- digitalRead
- Android
- Binary
- flutter
- stream
- Overloading
- wpf
- java
- APP
- UNO
- mfc
- Barcode
- atmega328
- preprocessing
- Class
- Read
- Unity
- file access
- memory
- parameter
- Contour
- public
- length
- Today
- Total
폴크(FOLC)
머신 비전 알고리즘 - 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;
cv::Size chess_board_size = cv::Size(chess_board_countX, chess_board_countY);
vector<vector<cv::Point3f> > ref_points, tar_points;
for (int i = 0; i < total_image_count; i++)
{
vector<cv::Point3f> ref_board_cross_point_corner;
int x = i % chess_board_countX;
int y = i / chess_board_countX;
ref_board_cross_point_corner.push_back(cv::Point3f(x * 28, y * 28, 0));
vector<cv::Point3f> tar_found_cross_point_corner;
int flags = cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE;
bool success = cv::findChessboardCorners(srcImage, chess_board_size, tar_found_cross_point_corner, flags);
if (success)
{
int type = cv::TermCriteria::EPS | cv::TermCriteria::MAX_ITER;
int maxCount = 30;
double epsilon = 0.001;
cv::TermCriteria criteria(type, maxCount, epsilon);
cv::Size winSize = cv::Size(11, 11), zeroZone = cv::Size(-1, -1);
cv::cornerSubPix(srcImage, tar_found_cross_point_corner, winSize, zeroZone, criteria);
cv::drawChessboardCorners(srcImage, chess_board_size, tar_found_cross_point_corner, success);
}
ref_points.push_back(ref_board_cross_point_corner);
tar_points.push_back(tar_found_cross_point_corner);
}
cv::Mat camera_instric_matrix, distortion_coeffs, rotation_vecs, translate_vecs;
cv::calibrateCamera(ref_points, tar_points, srcImage.size(), camera_instric_matrix, distortion_coeffs, rotation_vecs, translate_vecs);
cv::Mat map1, map2;
cv::Mat new_camera_matrix = cv::getOptimalNewCameraMatrix(camera_instric_matrix, distortion_coeffs, srcImage.size(), 1.0, srcImage.size(), 0);
cv::initUndistortRectifyMap(camera_instric_matrix, distortion_coeffs, cv::Mat(), new_camera_matrix, srcImage.size(), CV_16SC2, map1, map2);
// 보정수행
if (map1.data && map2.data)
{
remap(srcImage, dstImage, map1, map2, cv::INTER_LINEAR);
}
'머신 비전 > 머신 비전 알고리즘 테크닉 CPP' 카테고리의 다른 글
머신 비전 알고리즘 - OpenCV - 이미지처리5 (0) | 2021.07.24 |
---|---|
머신 비전 알고리즘 - OpenCV - 이미지처리4 (0) | 2021.07.24 |
머신 비전 알고리즘 - OpenCV - 이미지처리3 (0) | 2021.07.23 |
머신 비전 알고리즘 - OpenCV - 이미지처리2 (0) | 2021.07.22 |
머신 비전 알고리즘 - OpenCV - 이미지처리1 (0) | 2021.07.20 |