2017-02-07 3 views
2

나는 이더넷 연결을 통해 IP 카메라에서 이미지를 가져 오기 위해 파이썬을 사용하고 특정 대상을 찾도록 처리합니다. 특정 타겟 지역을 찾기 위해 코드를 생성하기 위해 GRIP을 사용하고 있습니다. (GRIP에 익숙하지 않은 사용자는 기본적으로 라이브 비디오 피드를보고 원하는 출력을 얻을 때까지 매개 변수를 변경할 수있는 GUI 데스크탑 인터페이스를 제공합니다. 그런 다음 Python으로 코드 마인을 자동 생성 할 수 있습니다. 코드에서 피드하는 모든 이미지에서 '파이프 라인 처리'를 수행하십시오.파이썬에서 이미지를 처리하기 위해 GRIP을 사용하는 세그먼트 화 오류

내 연결 코드를 광범위하게 디버깅 한 후 마침내 IP 카메라에서 이미지를 가져 와서 GRIP 파이프 라인으로 전송하는 성공적인 연결을 얻었습니다. 그러나 이미지 처리가 실패했으며 표시된 줄 번호가없는 분할 오류가 반환됩니다. 여기에 파이프 라인 코드 (자동 생성)입니다 :

import cv2 
import numpy 
import math 
from enum import Enum 

class GripPipeline: 
    """ 
    An OpenCV pipeline generated by GRIP. 
    """ 

    def __init__(self): 
     """initializes all values to presets or None if need to be set 
     """ 

     self.__blur_type = BlurType.Median_Filter 
     self.__blur_radius = 19.81981981981982 

     self.blur_output = None 

     self.__hsv_threshold_input = self.blur_output 
     self.__hsv_threshold_hue = [72.84172661870504, 86.31399317406144] 
     self.__hsv_threshold_saturation = [199.50539568345323, 255.0] 
     self.__hsv_threshold_value = [89.43345323741006, 255.0] 

     self.hsv_threshold_output = None 

     self.__find_contours_input = self.hsv_threshold_output 
     self.__find_contours_external_only = False 

     self.find_contours_output = None 

     self.__filter_contours_contours = self.find_contours_output 
     self.__filter_contours_min_area = 500.0 
     self.__filter_contours_min_perimeter = 0.0 
     self.__filter_contours_min_width = 0.0 
     self.__filter_contours_max_width = 1000.0 
     self.__filter_contours_min_height = 0.0 
     self.__filter_contours_max_height = 1000.0 
     self.__filter_contours_solidity = [0, 100] 
     self.__filter_contours_max_vertices = 1000000.0 
     self.__filter_contours_min_vertices = 0.0 
     self.__filter_contours_min_ratio = 0.0 
     self.__filter_contours_max_ratio = 1000.0 

     self.filter_contours_output = None 


    def process(self, source0): 
     """ 
     Runs the pipeline and sets all outputs to new values. 
     """ 
     # Step Blur0: 
     self.__blur_input = source0 
     (self.blur_output) = self.__blur(self.__blur_input, self.__blur_type, self.__blur_radius) 

     # Step HSV_Threshold0: 
     self.__hsv_threshold_input = self.blur_output 
     (self.hsv_threshold_output) = self.__hsv_threshold(self.__hsv_threshold_input, self.__hsv_threshold_hue, self.__hsv_threshold_saturation, self.__hsv_threshold_value) 

     # Step Find_Contours0: 
     self.__find_contours_input = self.hsv_threshold_output 
     (self.find_contours_output) = self.__find_contours(self.__find_contours_input, self.__find_contours_external_only) 

     # Step Filter_Contours0: 
     self.__filter_contours_contours = self.find_contours_output 
     (self.filter_contours_output) = self.__filter_contours(self.__filter_contours_contours, self.__filter_contours_min_area, self.__filter_contours_min_perimeter, self.__filter_contours_min_width, self.__filter_contours_max_width, self.__filter_contours_min_height, self.__filter_contours_max_height, self.__filter_contours_solidity, self.__filter_contours_max_vertices, self.__filter_contours_min_vertices, self.__filter_contours_min_ratio, self.__filter_contours_max_ratio) 


    @staticmethod 
    def __blur(src, type, radius): 
     """Softens an image using one of several filters. 
     Args: 
      src: The source mat (numpy.ndarray). 
      type: The blurType to perform represented as an int. 
      radius: The radius for the blur as a float. 
     Returns: 
      A numpy.ndarray that has been blurred. 
     """ 
     if(type is BlurType.Box_Blur): 
      ksize = int(2 * round(radius) + 1) 
      return cv2.blur(src, (ksize, ksize)) 
     elif(type is BlurType.Gaussian_Blur): 
      ksize = int(6 * round(radius) + 1) 
      return cv2.GaussianBlur(src, (ksize, ksize), round(radius)) 
     elif(type is BlurType.Median_Filter): 
      ksize = int(2 * round(radius) + 1) 
      return cv2.medianBlur(src, ksize) 
     else: 
      return cv2.bilateralFilter(src, -1, round(radius), round(radius)) 

    @staticmethod 
    def __hsv_threshold(input, hue, sat, val): 
     """Segment an image based on hue, saturation, and value ranges. 
     Args: 
      input: A BGR numpy.ndarray. 
      hue: A list of two numbers the are the min and max hue. 
      sat: A list of two numbers the are the min and max saturation. 
      lum: A list of two numbers the are the min and max value. 
     Returns: 
      A black and white numpy.ndarray. 
     """ 
     out = cv2.cvtColor(input, cv2.COLOR_BGR2HSV) 
     return cv2.inRange(out, (hue[0], sat[0], val[0]), (hue[1], sat[1], val[1])) 

    @staticmethod 
    def __find_contours(input, external_only): 
     """Sets the values of pixels in a binary image to their distance to the nearest black pixel. 
     Args: 
      input: A numpy.ndarray. 
      external_only: A boolean. If true only external contours are found. 
     Return: 
      A list of numpy.ndarray where each one represents a contour. 
     """ 
     if(external_only): 
      mode = cv2.RETR_EXTERNAL 
     else: 
      mode = cv2.RETR_LIST 
     method = cv2.CHAIN_APPROX_SIMPLE 
     im2, contours, hierarchy =cv2.findContours(input, mode=mode, method=method) 
     return contours 

    @staticmethod 
    def __filter_contours(input_contours, min_area, min_perimeter, min_width, max_width, 
         min_height, max_height, solidity, max_vertex_count, min_vertex_count, 
         min_ratio, max_ratio): 
     """Filters out contours that do not meet certain criteria. 
     Args: 
      input_contours: Contours as a list of numpy.ndarray. 
      min_area: The minimum area of a contour that will be kept. 
      min_perimeter: The minimum perimeter of a contour that will be kept. 
      min_width: Minimum width of a contour. 
      max_width: MaxWidth maximum width. 
      min_height: Minimum height. 
      max_height: Maximimum height. 
      solidity: The minimum and maximum solidity of a contour. 
      min_vertex_count: Minimum vertex Count of the contours. 
      max_vertex_count: Maximum vertex Count. 
      min_ratio: Minimum ratio of width to height. 
      max_ratio: Maximum ratio of width to height. 
     Returns: 
      Contours as a list of numpy.ndarray. 
     """ 
     output = [] 
     for contour in input_contours: 
      x,y,w,h = cv2.boundingRect(contour) 
      if (w < min_width or w > max_width): 
       continue 
      if (h < min_height or h > max_height): 
       continue 
      area = cv2.contourArea(contour) 
      if (area < min_area): 
       continue 
      if (cv2.arcLength(contour, True) < min_perimeter): 
       continue 
      hull = cv2.convexHull(contour) 
      solid = 100 * area/cv2.contourArea(hull) 
      if (solid < solidity[0] or solid > solidity[1]): 
       continue 
      if (len(contour) < min_vertex_count or len(contour) > max_vertex_count): 
       continue 
      ratio = (float)(w)/h 
      if (ratio < min_ratio or ratio > max_ratio): 
       continue 
      output.append(contour) 
     return output 


BlurType = Enum('BlurType', 'Box_Blur Gaussian_Blur Median_Filter Bilateral_Filter') 

그러나 나는 내가 다른 언어보다 파이썬 덜 잘 알고, 그 긴 실현, 그래서 경우에 모두를 제공하고 싶어 그렇게 많이 가진 사람 더 많은 파이썬 경험은 약간의 오류를 발견 할 수 있습니다.

import numpy 
import math 
import cv2 
import urllib.request 
from enum import Enum 
from GripPipeline import GripPipeline 
from networktables import NetworkTable 

frame = cv2.VideoCapture('https://10.17.11.1') 

pipeline = GripPipeline() 

def get_image() 
    img_array = numpy.asarray(bytearray(frame.grab())) 
    return img_array 
while True: 
    img = get_image() 
    pipeline.process(img) #where the Segmentation Fault occurs 

사람이 원인이나 해결 방법을하는 할 수 있는지에 대한 어떤 생각을 가지고 있습니까 : 여기

내가 이미지를 얻을 파이프 라인으로 먹이를 쓴 내 코드입니까?

편집 : 오류가 process 메서드의 두 번째 줄에있는 것으로부터 나온 것으로 나타났습니다. 그러나 나는 아직도 무엇을 모릅니다. 누군가가 거기에 불려지는 것에 결함을 발견하면 알려주십시오.

+0

이 질문 (행운을 빌어 세그먼트 폴트를 디버깅) 정말 관련이없는하지만 opencv''에 대한 관용적 StaticMethod를 데코레이터 뭔가를 사용하는 것입니다? 왜 이중 언더 스코어 이름 - mangling? 나는 모든 opencv 질문에 이것을 보는 것처럼 보입니다. 그리고 그것은 나를 견디게합니다! –

+0

오! 그것은 생성 된 코드입니다! 너무 경솔하게 unpythonic 경이. –

+0

@ juanpa.arrivillaga 나는 Java로 개발 한 모든 것의 90 %를 해왔지만,이 코드를 Raspberry Pi에서 실행 중이므로 일부 파이썬 기술을 빨리 습득하려고합니다. 거의 언제나 파이썬에서 코드 샘플을 볼 때마다 다른 규칙을 사용했습니다. –

답변

0

프레임을 가져 오는 시도는 tutorial을 제안합니다. 이름을 변경 프레임 캡 참고 :

cap = cv2.VideoCapture('https://10.17.11.1') 

pipeline = GripPipeline() 

while True: 
    ret, img = cap.read() 
    pipeline.process(img) 
+0

불행히도 이미지는 숫자가 적은 배열 형태 여야합니다. 그렇지 않으면 처리 할 수 ​​없습니다. –

+0

숫자 배열입니다. 제안 된대로 코드를 사용해 보셨습니까? 그렇지 않다면, 시도하십시오. 실패하면 오류 메시지를 제공하십시오. –

+0

알았습니다! 나는 그것이 반환 값의 숫자가 아닌 부분을받는 원인이되었다는 사실을 깨닫지 못하고'ret'를 빠져 나가고있었습니다. 도와 주셔서 감사합니다! –