윤곽에서 사각형을 감지
인터넷에 많이 있지만 사각형을 감지하는 곳까지의 기사가
인터넷에서는 적었기 때문에 써 보자고 생각했습니다.
내 블로그에서도 Canny에서 가장자리를 얻고 결정하는 기사를 썼습니다.
이진화 처리가 조금 복잡하고, 에센스의 부분을 알기 어려웠기 때문에,
한층 더 심플한 것을 게재하려고 합니다.
처리 흐름
프로그램은 Python과 OpenCV를 사용합니다.
근사 조건의 근사 곡선 최대 거리를 윤곽 길이의 0.02로 한다(0.02는 임의)
근사 처리에는 cv2.approxPolyDP()를 사용합니다.
1. 뿔이 4개 있다
2. 면적값이 조건 이상 있음
3. 볼록 형상이다
isContourConvex() 사용
4. 각 변이 이루는 모서리의 최대 코사인이 0.3 이하.
삼각함수 코사인이 0.3을 취하는 것은 아래 그림을 보는 조정이 됩니다.
정사각형은 코사인 1.0이 이상적인 값입니다.
삼각 함수 그래프
샘플 코드
findSquares.pyimport cv2
import math
import numpy as np
# pt0-> pt1およびpt0-> pt2からの
# ベクトル間の角度の余弦(コサイン)を算出
def angle(pt1, pt2, pt0) -> float:
dx1 = float(pt1[0,0] - pt0[0,0])
dy1 = float(pt1[0,1] - pt0[0,1])
dx2 = float(pt2[0,0] - pt0[0,0])
dy2 = float(pt2[0,1] - pt0[0,1])
v = math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) )
return (dx1*dx2 + dy1*dy2)/ v
# 画像上の四角形を検出
def findSquares(bin_image, image, cond_area = 1000):
# 輪郭取得
contours, _ = cv2.findContours(bin_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for i, cnt in enumerate(contours):
# 輪郭の周囲に比例する精度で輪郭を近似する
arclen = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, arclen*0.02, True)
#四角形の輪郭は、近似後に4つの頂点があります。
#比較的広い領域が凸状になります。
# 凸性の確認
area = abs(cv2.contourArea(approx))
if approx.shape[0] == 4 and area > cond_area and cv2.isContourConvex(approx) :
maxCosine = 0
for j in range(2, 5):
# 辺間の角度の最大コサインを算出
cosine = abs(angle(approx[j%4], approx[j-2], approx[j-1]))
maxCosine = max(maxCosine, cosine)
# すべての角度の余弦定理が小さい場合
#(すべての角度は約90度です)次に、quandrangeを書き込みます
# 結果のシーケンスへの頂点
if maxCosine < 0.3 :
# 四角判定!!
rcnt = approx.reshape(-1,2)
cv2.polylines(image, [rcnt], True, (0,0,255), thickness=2, lineType=cv2.LINE_8)
return image
def main():
image = cv2.imread('shapes_image.png', cv2.IMREAD_COLOR)
if image is None :
exit(1)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, bw = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
rimage = findSquares(bw, image)
cv2.imshow('Square Detector', rimage)
c = cv2.waitKey()
return 0;
if __name__ == '__main__':
main()
입력 이미지
위의 도형에서 사각형을 감지합니다.
결과 이미지
윤곽을 빨간색으로 둘러싼 곳이 검출한 사각형입니다.
임계값은 단맛이 되어 있으므로, 좌하의 사다리꼴도 검출하고 있습니다.
운영 환경
Windows10
아나콘다 3
파이썬 3.9.0
OpenCV 4.4.0
numpy 1.19.2
요약
이 방법은 docs.opencv.org - samples/cpp/squares.cpp의 샘플 코드를보고,
그것을 참고로 하고 있습니다.
기하학 계산뿐이므로이 트릭은 그리 어렵지 않고 잘하는 방법입니다.
감탄했습니다.
실제로 이미지 처리로 사용하려면 이진화 또는 에지 감지 및 윤곽 근사 조정이
간이 될까 생각합니다.
참고
Emotion Explorer - OpenCV 사각형 감지
docs.opencv.org - samples/cpp/squares.cpp
docs.opencv.org - Structural Analysis and Shape Descriptors
Reference
이 문제에 관하여(윤곽에서 사각형을 감지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sitar-harmonics/items/ac584f99043574670cf3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import cv2
import math
import numpy as np
# pt0-> pt1およびpt0-> pt2からの
# ベクトル間の角度の余弦(コサイン)を算出
def angle(pt1, pt2, pt0) -> float:
dx1 = float(pt1[0,0] - pt0[0,0])
dy1 = float(pt1[0,1] - pt0[0,1])
dx2 = float(pt2[0,0] - pt0[0,0])
dy2 = float(pt2[0,1] - pt0[0,1])
v = math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) )
return (dx1*dx2 + dy1*dy2)/ v
# 画像上の四角形を検出
def findSquares(bin_image, image, cond_area = 1000):
# 輪郭取得
contours, _ = cv2.findContours(bin_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for i, cnt in enumerate(contours):
# 輪郭の周囲に比例する精度で輪郭を近似する
arclen = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, arclen*0.02, True)
#四角形の輪郭は、近似後に4つの頂点があります。
#比較的広い領域が凸状になります。
# 凸性の確認
area = abs(cv2.contourArea(approx))
if approx.shape[0] == 4 and area > cond_area and cv2.isContourConvex(approx) :
maxCosine = 0
for j in range(2, 5):
# 辺間の角度の最大コサインを算出
cosine = abs(angle(approx[j%4], approx[j-2], approx[j-1]))
maxCosine = max(maxCosine, cosine)
# すべての角度の余弦定理が小さい場合
#(すべての角度は約90度です)次に、quandrangeを書き込みます
# 結果のシーケンスへの頂点
if maxCosine < 0.3 :
# 四角判定!!
rcnt = approx.reshape(-1,2)
cv2.polylines(image, [rcnt], True, (0,0,255), thickness=2, lineType=cv2.LINE_8)
return image
def main():
image = cv2.imread('shapes_image.png', cv2.IMREAD_COLOR)
if image is None :
exit(1)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, bw = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
rimage = findSquares(bw, image)
cv2.imshow('Square Detector', rimage)
c = cv2.waitKey()
return 0;
if __name__ == '__main__':
main()
위의 도형에서 사각형을 감지합니다.
결과 이미지
윤곽을 빨간색으로 둘러싼 곳이 검출한 사각형입니다.
임계값은 단맛이 되어 있으므로, 좌하의 사다리꼴도 검출하고 있습니다.
운영 환경
Windows10
아나콘다 3
파이썬 3.9.0
OpenCV 4.4.0
numpy 1.19.2
요약
이 방법은 docs.opencv.org - samples/cpp/squares.cpp의 샘플 코드를보고,
그것을 참고로 하고 있습니다.
기하학 계산뿐이므로이 트릭은 그리 어렵지 않고 잘하는 방법입니다.
감탄했습니다.
실제로 이미지 처리로 사용하려면 이진화 또는 에지 감지 및 윤곽 근사 조정이
간이 될까 생각합니다.
참고
Emotion Explorer - OpenCV 사각형 감지
docs.opencv.org - samples/cpp/squares.cpp
docs.opencv.org - Structural Analysis and Shape Descriptors
Reference
이 문제에 관하여(윤곽에서 사각형을 감지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sitar-harmonics/items/ac584f99043574670cf3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Windows10
아나콘다 3
파이썬 3.9.0
OpenCV 4.4.0
numpy 1.19.2
요약
이 방법은 docs.opencv.org - samples/cpp/squares.cpp의 샘플 코드를보고,
그것을 참고로 하고 있습니다.
기하학 계산뿐이므로이 트릭은 그리 어렵지 않고 잘하는 방법입니다.
감탄했습니다.
실제로 이미지 처리로 사용하려면 이진화 또는 에지 감지 및 윤곽 근사 조정이
간이 될까 생각합니다.
참고
Emotion Explorer - OpenCV 사각형 감지
docs.opencv.org - samples/cpp/squares.cpp
docs.opencv.org - Structural Analysis and Shape Descriptors
Reference
이 문제에 관하여(윤곽에서 사각형을 감지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sitar-harmonics/items/ac584f99043574670cf3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Emotion Explorer - OpenCV 사각형 감지
docs.opencv.org - samples/cpp/squares.cpp
docs.opencv.org - Structural Analysis and Shape Descriptors
Reference
이 문제에 관하여(윤곽에서 사각형을 감지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sitar-harmonics/items/ac584f99043574670cf3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)