반응형
때로는 이미지나 영상에서 가장 긴 직선이 이미지 회전의 기준이 되기도 한다.
Hough Transform을 이용하여 직선성분을 검출한다.
검출된 직선 중 가장 긴 직선을 기준으로 회전된 각도를 반환한다.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | double getRotationAngle(const IplImage* src) { // Only 1-Channel if(src->nChannels != 1) return 0; // 직선이 잘 검출될 수 있도록 팽창 cvDilate((IplImage*)src, (IplImage*)src); // 저장영역 생성 CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* seqLines; // Image의 직선영역을 seq에 저장(rho, theta) seqLines = cvHoughLines2((IplImage*)src, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 30, 3); // 인자들 수정해야함 // 직선들의 거리를 구해서 가장 긴 직선을 기준으로 이미지 0 or 90도로 회전 double longDistance = 0; // 직선 중 가장 긴 길이 int longDistanceIndex = 0; // 직선 중 가장 긴 길이 인덱스 for (int i = 0; i < seqLines->total; i++){ CvPoint* lines = (CvPoint*)cvGetSeqElem(seqLines, i); double euclideanDistance; // sequence에 저장된 line들의 Euclidean distance를 저장 euclideanDistance = (lines[1].x - lines[0].x) * (lines[1].x - lines[0].x) + (lines[1].y - lines[0].y) * (lines[1].y - lines[0].y); euclideanDistance = sqrt(euclideanDistance); // 가장 긴 Euclidean distance를 저장 if(longDistance < euclideanDistance){ longDistanceIndex = i; longDistance = euclideanDistance; } //// 직선영역 제거 //cvLine((IplImage*)src, lines[0], lines[1], CV_RGB(0, 0, 0), 3, CV_AA); } //// check the longest line //CvPoint* lines = (CvPoint*)cvGetSeqElem(seqLines, longDistanceIndex); //cvLine((IplImage*)src, lines[1], lines[0], CV_RGB(125, 125, 125), 3, CV_AA); //cout<<"pt1("<<lines[0].x<<", "<<lines[0].y<<") pt2("<<lines[1].x<<", "<<lines[1].y<<")"<<endl; // 회전된 각도 계산 CvPoint* lines = (CvPoint*)cvGetSeqElem(seqLines, longDistanceIndex); int dx = lines[1].x - lines[0].x; int dy = lines[1].y - lines[0].y; double rad = atan2((double)dx, (double)dy); // 회전된 각도(radian) double degree = abs(rad * 180) / CV_PI; // 회전된 각도(degree) 저장 // 회전된 각도보정 if(degree>90) degree-=90; // 메모리 해제 cvClearSeq(seqLines); cvReleaseMemStorage(&storage); return degree; } |
728x90
반응형
'Programming > Image Processing' 카테고리의 다른 글
[OpenCV] IplImage 이미지 회전 함수구현 (1) | 2014.02.21 |
---|---|
[OpenCV] 이미지 로드 + 출력예제 소스코드 (0) | 2014.02.08 |
[OpenCV] Labeling 응용(가장 많은 화소 Label만 남기기) Source Code (0) | 2014.02.02 |
[OpenCV] 2.4 이상 버전에서 SIFT + SURF 사용 설정 (3) | 2014.01.27 |
[OpenCV] Labeling(레이블링, 라벨링) 이론 및 소스코드 (3) | 2014.01.14 |