OpenCV 윤곽 검 측 실현 방법

7136 단어 OpenCV윤곽 검사
윤곽 개술
4.567917.윤곽 은 연속 적 인 점(경계 연결)을 연결 하 는 곡선 으로 간단하게 볼 수 있 고 같은 색깔 이나 그 레이스 케 일 을 가진다.윤곽 은 형상 분석 과 물체 의 검 측 과 식별 에 매우 유용 하 다.  4.567917.더욱 정확 하기 위해 이치 화 이미 지 를 사용 해 야 한다.윤곽 을 찾기 전에 한도 값 화 처리 나 캐 니 경계 검 사 를 해 야 한다.  4.567917.윤곽 을 찾 는 함수 가 원본 그림 을 수정 합 니 다.윤곽 을 찾 은 후에 도 원본 그림 을 사용 하려 면 원본 그림 을 다른 변수 에 저장 해 야 합 니 다. 
  • OpenCV 에서 윤곽 을 찾 는 것 은 검은색 배경 에서 초 흰색 물체 와 같 고 찾 는 물 체 는 흰색 이 어야 하 며 배경 은 검은색 이 어야 한다.
  • 윤곽 검사 의 역할:
    1.그림 이나 영상 속 물체 의 윤곽 을 감지 할 수 있다.
    2.다각형 경 계 를 계산 하고 모양 이 가 까 워 지고 관심 있 는 구역 을 계산한다.
    먼저 비교적 간단 한 윤곽 검 사 를 보십시오.
    
    import cv2
    import numpy as np
    #     200*200       
    img = np.zeros((200, 200), dtype=np.uint8)
    #   numpy                   
    img[50:150, 50:150] = 255
    
    #           
    # threshold(src, thresh, maxval, type, dst=None)
    # src     ,thresh       ,maxval type THRESH_BINARY  THRESH_BINARY_INV     
    # type 5   ,   0: THRESH_BINARY ,         , maxval,        ,    0
    #               ,           
    ret, thresh = cv2.threshold(img, 127, 255, 0)
    
    # findContours()     :    ,           
    #          ,    img.copy()    
    #             ,cv2.RETR_TREE               ,          ‘  '。
    #             ,    cv2.RETE_EXTERNAL。              ,        
    #          :      ,     ,     
    image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)
    cv2.imshow("contours", color)
    cv2.waitKey()
    cv2.destroyAllWindows()

    위 는 정사각형 의 윤곽 을 찾 았 습 니 다.아래 는 불규칙 한 다각형 윤곽 을 어떻게 찾 는 지 보 겠 습 니 다.
    
    import cv2
    import numpy as np
    
    # pyrDown():brief Blurs an image and downsamples it.
    #        ,       
    img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
    #         
    ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
    #        
    image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    for c in contours:
      # find bounding box coordinates
      #             ,        
      #           (x,y)  ,           
      x, y, w, h = cv2.boundingRect(c)
      #      
      cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    
      # find minimum area
      #                
      #             ,         ,          ,         
      #            
      rect = cv2.minAreaRect(c)
      box = cv2.boxPoints(rect)
      box = np.int0(box)
      # draw contours
      #       
      # drawContours()       
      #             ,          
      #                  :-1        ,     [box]      
      #    thickness(  ,    )        
      cv2.drawContours(img, [box], 0, (0, 0, 255), 3)
    
      # calculate center and radius of minimum enclosing circle
      #               
      # minEnclosingCircle()         ,             ,          
      (x, y), radius = cv2.minEnclosingCircle(c)
      # cast to integers
      center = (int(x), int(y))
      radius = int(radius)
      # draw the circle
      img = cv2.circle(img, center, radius, (255, 0, 0), 3)
    
    #     
    cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
    cv2.imshow("contours", img)
    
    cv2.waitKey()
    cv2.destroyAllWindows()

    볼록 윤곽 과 Douglas-Peucker 알고리즘
    
    import cv2
    import numpy as np
    
    img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
    
    ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
    #              
    black = cv2.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv2.COLOR_GRAY2BGR)
    
    image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    for cnt in contours:
      #            
      epsilon = 0.01 * cv2.arcLength(cnt,True)
      # approxPolyDP()           。     
      # cnt   ,epsilon ε――                ,     
      #         ,             
      approx = cv2.approxPolyDP(cnt,epsilon,True)
      # convexHull()          
      hull = cv2.convexHull(cnt)
      #      -  
      cv2.drawContours(black, [cnt], -1, (0, 255, 0), 2)
      #      -  
      cv2.drawContours(black, [approx], -1, (255, 0, 0), 2)
      #   -  
      cv2.drawContours(black, [hull], -1, (0, 0, 255), 2)
    
    cv2.imshow("hull", black)
    cv2.waitKey()
    cv2.destroyAllWindows()

    원래 도 의문 이 있 었 는데,정확 한 윤곽 이 생 겼 는데,왜 비슷 한 다각형 이 필요 합 니까?
    책 에서 답 을 내 놓 았 는데 근사 다각형 은 하나의 직선 으로 구성 되 어 있어 후속 적 인 조작 과 처리 에 편리 하 다.
    생각해 보 니 직선 으로 구 성 된 구역 은 항상 무한 곡률 의 곡선 으로 구 성 된 구역 보다 처리 하기 쉽다.
    직선 과 원 검 측
    직선 검 사 는 HoughLinesP 함 수 를 통 해 이 루어 질 수 있 으 며 HoughLinesP 는 표준 Hough 변환 이 최적화 되 어 사용 확률 Hough 변환 을 거 친다.
    
    import cv2
    import numpy as np
    
    img = cv2.imread('lines.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,50,120)
    #       ,         
    minLineLength = 20
    #       ,                       
    maxLineGap = 5
    # HoughLinesP()      Canny                  
    #      Canny   ,               ,     
    #           
    #   、             rho theta,   1 np.pi/180
    #         ,            
    #         
    lines = cv2.HoughLinesP(edges,1,np.pi/180,20,minLineLength,maxLineGap)
    for x1,y1,x2,y2 in lines[0]:
      cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
    
    cv2.imshow("edges", edges)
    cv2.imshow("lines", img)
    cv2.waitKey()
    cv2.destroyAllWindows()
    원 검 사 는 Hough Circles 함 수 를 통 해 검 측 할 수 있 습 니 다.
    
    import cv2
    import numpy as np
    
    planets = cv2.imread('planet_glow.jpg')
    gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
    img = cv2.medianBlur(gray_img, 5)
    cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    
    #        ,                     
    circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
    
    circles = np.uint16(np.around(circles))
    
    for i in circles[0,:]:
      # draw the outer circle
      cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
      # draw the center of the circle
      cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)
    
    cv2.imwrite("planets_circles.jpg", planets)
    cv2.imshow("HoughCirlces", planets)
    cv2.waitKey()
    cv2.destroyAllWindows()
    이 방법 으로 검출 된 두 번 째 줄 의 첫 번 째 별의 원 검출 은 책 과 다르다.

    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기