본문 바로가기
opencv

공백 메우기

by 꼰대코더 2023. 12. 2.

왼쪽과 같은 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);
}

hull 포인트(붉은점들)


배경이 검은 새로운 이미지 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));

hull 포인트들을 연결(노란선)

'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