상자 안에 인쇄 된 개체를 제거하는 동안 이미지의 상자를 감지하는 방법?
-
02-01-2020 - |
문제
나는 상자 정렬 응용 프로그램을 개발하기 위해 노력하고 있습니다.나는 상자의 폭과 길이를 측정 할 수 있습니다.
위의 이미지와 같이 가장 바깥 쪽 선(즉,가장 바깥 쪽 선)만 감지하고 싶습니다.상자 가장자리),상자 내부에 인쇄 된 것과 관계없이 상자의 너비와 길이를 제공합니다.
내가 시도한 것:
먼저 나는
Findcontours()
그리고 최대 면적의 윤곽을 선택했지만,바깥 가장자리의 윤곽은 여러 번(지혜로운 출력에서 어딘가에 깨진)동봉되지 않으며 따라서 윤곽으로 감지되지 않습니다.허프 라인 변환은 나에게 너무 많은 라인을 제공합니다,나는 단지 네 줄이 그 중에서에 관심이 얻는 방법을 모르겠어요.
나는 내 알고리즘을 다음과 같이 시도했다,
이미지를 그레이 스케일로 변환합니다.
이미지의 한 열을 가져 와서 모든 픽셀을 해당 열의 다음 연속 픽셀과 비교하십시오.이 값의 차이가 픽셀이 가장자리에 속한 일부 임계 값(예:100)보다 크면 배열에 저장하십시오.모든 열에 대해이 작업을 수행하고 상자 평행선의 상단 라인을 줄 것이다 엑스 축.
동일한 절차를 따르지만 마지막 열과 마지막 행(즉.아래에서 위로),그것은 축에 평행 한 낮은 선을 줄 것이다.
마찬가지로 찾기 선 평행 와이 축 뿐만 아니라.이제 각 변에 하나씩 4 개의 점 배열이 있습니다.
이제 이것은 나에게 좋은 결과를 제공합니다 상자 그 변이 정확히 평행 한 방식으로 배치되는 경우 엑스 과 와이 축.박스도 약간 어떤 방향으로 지향 배치되는 경우,그것은 나에게 아래 이미지와 같이 분명 대각선 라인을 제공합니다.
아래 이미지와 같이 나는(대각선을 그리기에 대한 책임이 있습니다)점의 네 배열에서 처음 10 마지막 10 점을 제거하고 상자가 더 기울어 또한 측정이 잘못 될 때 작동하지 않을 선을 그렸다.
이제 내 질문은,
상자의 바깥 쪽 가장자리(사각형)만 가져 와서 상자에 인쇄 된 것을 무시하고 어떤 방향으로 지향하는 더 간단한 방법이 있습니까?
나는 반드시 내 알고리즘을 수정/개선 할 것을 요구하지는 않지만 그에 대한 제안도 환영합니다.이렇게 큰 포스팅에 대해 죄송합니다.
해결책
나는 다음 단계를 제안 할 것이다:
1:다음을 사용하여 마스크 이미지 만들기 cv::inRange()
(문서)배경색을 선택합니다.그런 다음 사용 cv::not()
이 마스크를 뒤집습니다.이것은 당신에게 상자 만 줄 것입니다.
2:당신은 그림자에 대해 걱정하지 않는 경우,깊이 효과는 측정을 부정확하게 당신은 사용하려고 바로 진행할 수 있습니다 cv::findContours()
다시.당신은 가장 큰 윤곽을 선택하고 그것을 저장 cv::rotatedRect
.
3:이 cv::rotatedRect
당신에게 회전식 직접을 줄 것입니다.픽셀 단위로 상자의 높이 엉 너비를 정의하는 크기
다른 팁
상자가 대조적 인 배경에 배치되므로 OTSU 임계 값을 사용할 수 있어야합니다.
- 임계 값 이미지 (OTSU 방법 사용)
- 상자 밖에있는 길은 픽셀을 필터링합니다 (많은 그러한 픽셀을 얻지 않으려 고하며 중간 또는 형태 학적 필터로 쉽게 제거 할 수 있기를 바랍니다)
- 윤곽 찾기 를 찾습니다
- 모든 윤곽선을 결합하고 그들의 볼록한 선체를 얻으십시오.
- 이 볼록한 선체에 다각형 근사치 (대략 적혈구)를 적용하고 사변형 를 확인하십시오.
- 관점 왜곡이없는 경우 사각형을 가져와야합니다. 그렇지 않으면 를 수정해야합니다.
- 사각형을 얻으면 치수가 있습니다.convevexhull의 최소 영역 사각형 (minarearect)을 찾을 수 있습니다. 이는 RotatedRect 를 직접 제공해야합니다.