왼쪽과 같은 b/w 이미지를 오른쪽과 같이 공백을 메우는 방법을 OpenCV로 알아보자.
아울러 아래의 기법도 확실히 알아두기로 하자.
- findNonZero 함수를 이용한 흰픽셀의 좌표얻기
- convexHull 함수를 이용한 어바우트한 윤곽 포인트 획득
이미지를 그레이스케일 변환하여 읽어 들이고 10 을 기준으로 b/w 변환한다.
cv::Mat inputImage = cv::imread("input.jpg", CV_LOAD_IMAGE_GRAYSCALE);
cv::threshold(inputImage, inputImage, 10, 255, 0);
b/w 이미지내에서 흰색픽셀의 좌표를 찾아내서 Mat 안에 보관
v::Mat nonZeroCoordinates;
cv::findNonZero(inputImage, nonZeroCoordinates);
Mat 구조에서 Point 의 배열로 변환
std::vector<cv::Point> points;
for (int i = 0; i < nonZeroCoordinates.total(); i++){
points.push_back(nonZeroCoordinates.at<cv::Point>(i));
}
흰색의 좌표 포인트 배열로 부터 굴곡을 무시한 어바우트한 외곽 후보 포인트 배열 인덱스를 hull 에 저장
std::vector<int> hull;
// 그냥 points 을 써도 되지 않을까?
cv::convexHull(cv::Mat(points), hull, false);
포인트 인덱스가 들어있는 hull 로부터 실제 포인트 좌표를 hullpoints 에 저장
std::vector<cv::Point> hullpoints;
int hullcount = (int)hull.size();
for (int i = 0; i < hullcount; i++) {
cv::Point pt = points[hull[i]];
hullpoints.push_back(pt);
}
배경이 검은 새로운 이미지 Mat을 만들어 hull 좌표들 안쪽으로 흰색(255)로 채운다.
fillPoly 함수의 두번째 파라미터가 2중 std::vector<std::vector<cv::Point>> 를 원하기 때문에 1차원 배열을 2중 배열형식으로 맞춰주고 있다.
std::vector<std::vector<cv::Point> > fillContAll;
fillContAll.push_back(hullpoints);
cv::Mat result = cv::Mat::zeros(inputImage.size(), CV_8UC1);
cv::fillPoly(result, fillContAll, cv::Scalar(255));
'opencv' 카테고리의 다른 글
contour / labelling (0) | 2023.12.07 |
---|---|
b/w 이미지의 칼럼(수직방향)별 검정(=0)픽셀수 카운트 (0) | 2023.12.02 |
cv::Mat 이모저모 (1) | 2023.11.29 |
이미지 회전 (0) | 2023.11.27 |
스캔문서의 기울기 알아보기 - 2 (0) | 2023.11.27 |