스캔문서의 기울기 알아보기 에서 라인을 통해 기울기를 알아 보았다. 이번 칼럼에서는 단락을 통해 기울기를 알아보는 방법을 살펴보자.
그레이 변환 ▶ B/W 변환 ▶ 문자를 흰색으로 변환 ▶ 문자(흰픽셀) 좌표만 Point배열에 저장 ▶ minAreaRect 함수를 통해 각도 확인 ▶ 각도 보정
이번에 사용할 이미지는 지난번 이미지에서 단락 부분만 떼어 내었다. 만약 전체 이미지를 사용하고자 한다면 단락간의 공간을 찾아내어 한 단락만 떼어내는 로직이 필요할 것이다.
1. 그레이 변환, B/W 변환, 문자를 흰색으로 변환
cv::Mat image = cv::imread("d:\\image.png");
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
cv::threshold(image, image, 100, 255, cv::THRESH_BINARY);
cv::bitwise_not(image, image);
2. 문자(흰픽셀) 좌표만 Point배열에 저장
std::vector<cv::Point> points;
// 이미지 픽셀 데이터의 처음과 끝의 포인터
cv::Mat_<uchar>::iterator it = image.begin<uchar>();
cv::Mat_<uchar>::iterator end = image.end<uchar>();
// 픽셀 전체를 루프하여 흰색(*it != 0)인 경우만 배열에 추가
for (; it != end; ++it)
if (*it)
points.push_back(it.pos());
※ cv::Mat_ 은 cv::Mat 에서 파생된 template 클래스이다. cv::Mat 의 기능을 유지하면서 새롭게 iterator 가 추가되었다.
3. 각도 그외 부과 정보 확인
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
std::cout << "angle " << box.angle << std::endl;
std::cout << "boundingRect " << box.boundingRect() << std::endl;
std::cout << "boundingRect2f " << box.boundingRect2f() << std::endl;
std::cout << "center " << box.center << std::endl;
4. 각도 보정
cv::minAreaRect 의 결과물인 각도는 계산 방법이 조금 복잡하다. ( 여기 참조 )
결과 각도는 항상 0 ~ -90 사이이다.
원래 문서의 Width Height 사이즈의 관계와 boundingRect 의 Width Height 사이즈 관계에 따라 달리 처리를 해야한다.
아래를 보면 같은 -90도라도 Width Height 사이즈 관계에 따라 형태가 다름을 알수 있다.
보통 단락은 Width > Height 관계라 생각했을때 출력 될 수 있는 각도는 빨간원의 형태라 볼 수 있고 본 샘플의 결과가 -87.323 의 각도이기 때문에 위 그림에서 맨 밑의 -79.958 과 비슷한 형태로 기울어져 있음을 알수 있다.
// 회전해야 할 각도 구하기
// 회전은 반시계방향으로 plus 가 반시계 방향을 의미한다.
double rotation_angle = 0.0;
if (angle <= -45)
rotation_angle = angle + 90.0;
else
rotation_angle = angle + 360.0;
스캔문서의 기울기 알아보기 와 같은 결과값의 표현의 각도는 2.677 (= -87.323 + 90.0) 이다.
'opencv' 카테고리의 다른 글
cv::Mat 이모저모 (1) | 2023.11.29 |
---|---|
이미지 회전 (0) | 2023.11.27 |
스캔문서의 기울기 알아보기 (0) | 2023.11.26 |
(opencv) 이미지 저장형태, 액서스 (1) | 2023.11.25 |
(opencv) Rectangle 간의 조작에 관해 (1) | 2023.11.23 |