2017-01-29 11 views
2

큰 프로젝트의 경우 현재 PLAN (Stanford Polygon File) 파서를 작성하는 중입니다. Github Gists의 예제는 현재 ASCII 형식 PLY 파일을 데이터 추상화 Mesh으로 구문 분석 할 수 있습니다. 그것은 또한 기울어 진 사람들을 위해 실제 문법에 대한 설명을 포함합니다.Pyparsing을 사용하여 이진 스탠포드 다각형 파일 (PLY) 구문 분석

그러나 형식 정의 (PLY - Polygon File Format)에는 2 개의 2 진 형식 (리틀 및 빅 엔디안)도 포함됩니다. 이 두 형식은 훨씬 더 보편적이며 저장 공간 효율성이 뛰어 나기 때문에 pyparsing으로 파일을 구문 분석 할 수 있기를 바랍니다.

나는 가능하면 그렇게하는 방법에 대한 조언을 해주셔서 감사합니다.

이진 PLY 파일의 개념은 헤더 부분이 파일의 실제 데이터에 대한 ASCII 설명으로 구성되며 본문에 실제 데이터가 들어 있다는 것입니다. 예 (괄호 안의 데이터를 16 진수 바이트) : 내 첫 번째 방법은 그냥 (대신 strbytes 사용) 바이너리 형식의 입력 파일을로드하고 그에 따라 파서를 적용했다, 그러나 이것은 어떻게 든 pyparsing을 던졌습니다

ply 
format binary_little_endian 1.0   
element vertex 1 
property float x 
property float y 
property float z 
property uchar red 
property uchar green 
property uchar blue 
property uchar alpha 
end_header 
[84 72 F1 C1 D8 FD 9F C1 00 00 00 00 3B 45 CB FF] 

오프 트랙. 또한, 나는 정말로 바이트 그룹을 grok하는 방법을 알려주는 pyparsing을 모른다.

File "components.py", line 338, in create 
    mesh = PlyParser.create().load(mesh_path) 
    File "model_parser.py", line 120, in create 
    property_position = aggregate_property("position", b"x", b"y", b"z") 
    File "model_parser.py", line 113, in aggregate_property 
    aggregates.append(pp.Group(property_simple_prefix + keyword_or(*keywords)("name"))) 
    File "model_parser.py", line 87, in keyword_or 
    return pp.Or(pp.CaselessKeyword(literal) for literal in keywords) 
    File "pyparsing.py", line 3418, in __init__ 
    super(Or,self).__init__(exprs, savelist) 
    File "pyparsing.py", line 3222, in __init__ 
    exprs = list(exprs) 
    File "model_parser.py", line 87, in <genexpr> 
    return pp.Or(pp.CaselessKeyword(literal) for literal in keywords) 
    File "pyparsing.py", line 2496, in __init__ 
    super(CaselessKeyword,self).__init__(matchString, identChars, caseless=True) 
    File "pyparsing.py", line 2422, in __init__ 
    self.matchLen = len(matchString) 
TypeError: object of type 'int' has no len() 
+0

'pyparsing'은 텍스트를 대상으로합니다. 아마도 바이너리 스트림을 텍스트 스트림으로 변환하는 데 도움이 될 수 있습니다. 예를 들어 base64 인코딩과 구문 분석을 통해 말입니다. – halloleo

+0

@halloleo 제안에 감사드립니다. 불행히도 PLY 파일은 파트 텍스트이며 일부는 바이너리입니다. 따라서 필자는 파일을 미리로드하고 이진 부분을 base64와 같은 것으로 인코딩 한 다음이를 pyparsing으로 구문 분석해야합니다. 또한 때로는 100MB 이상의 MiB 파일을 인코딩하는 것은 실제로 내가하고 싶은 것이 아닙니다. –

답변

1

텍스트로 파일을 열고, 훑어보기를 사용하여 헤더를 구문 분석하고 "끝 헤더"토큰의 끝 위치를 캡처하는 것이 좋습니다. 헤더에서 추출한 구조 정보를 사용하여 바이너리 컨텐츠를 처리 할 Python 구조 판독기를 작성하십시오. 그런 다음 이진 파일로 파일을 다시 열어 위치를 찾은 다음 구조 판독기를 사용하여 이진 내용을로드합니다. 텍스트와 바이너리 모두로 삐삐를 꼬는 것보다 간단합니다.

+0

나는 당신의 제안과 함께 가고, struct 모듈을 사용하기로 결정했다. 업데이트 된 코드는 원래 요점 : [PlyParser] (https://gist.github.com/youngec/76c5b552ab5bc04b43d1bfa9d3fa0a78)에서 확인할 수 있습니다. –

1

이미 진 PLY 파일을 구문 분석하기위한 모듈이있다 : python-plyfile.

이 코드를 사용하거나 최소한 소스 코드를보고 어떻게 작동하는지 알 수 있습니다.

이것은 "알려진 데이터 유형의 이진 데이터를 매우 효율적으로 읽는 방법"이라고 표현되는 이진 데이터 읽기에 대해 numpy.fromfile을 사용합니다.

+0

팁 주셔서 감사! 불행히도,'python-plyfile'은 이진 데이터를 중첩 및/또는 구조화 된 numpy 배열로 구문 분석하는 데이터 모델을 사용합니다. 필자의 경우, 연속적인 스토리지가 필요했습니다. 또한,이 프로젝트에 numpy를 사용하지 않으려 고합니다. –