2014-02-13 1 views
1

os.walk를 사용하지 않고 디렉토리를 통과하는 스크립트 (예 : os.walk와 거의 동일)를 작성하려고합니다. 그 이유는 각 디렉토리가 이미지 시퀀스로 가득 차고 os.walk가 너무 많은 시간을 들여야하기 때문입니다.디렉토리에서 이미지 시퀀스 찾기 - os.walk()보다 빠름?

내 의도는 각 이미지 시퀀스의 파일 이름을 수집하는 것입니다. 그래서 현재 시퀀스의 단일 이미지가 발견 되 자마자 루프에서 벗어납니다. 디렉토리에 단 하나의 이미지 시퀀스가 ​​있으면 잘 작동하지만 디렉토리에 이미지 시퀀스가 ​​2 개 이상 있으면 어떻게됩니까? 이것은 제가 풀려나는 곳입니다.

def find_all_ImageSequences(dir): 

    for object in os.listdir(dir): 
     if os.path.isdir(dir + "\\" + str(object)): 
      find_all_ImageSequences(dir + "\\" + str(object)) 
     else: 
      if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')): 
       Image_Sequences_List.append(dir + "\\" + str(object)) 
       image_filename = object.split(".")[0] 
       extras = [x for x in os.listdir(dir) if x.split(".")[0] != image_filename] 
       if extras: 
        "try to take the 1st image and add it to my Image_Sequences_List" 
       break 

은 "엑스트라"지능형리스트가 두 번째 이미지 시퀀스를 찾았다 후에도, 그 디렉토리에있는 모든 개체를 통해 보는 것 :

이것은 내가 지금까지있는 것입니다. 다음 이미지 시퀀스의 첫 번째 프레임이 발견되는 즉시이를 중단 할 수 있습니까?

내가 사용하는 방법에 대한 생각 :

if any([x for x in os.listdir(dir) if x.split(".")[0] != image_filename]): 
    "do something" 

그러나 이것은 내가 그 다음 순서를 찾기 위해 다시 현재 디렉토리를 반복 할 것 같은 카운터 생산성을 보였다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 성능을 향상 인 os.walk 교체가 https://github.com/benhoyt/scandir을 확인하려면

def find_all_ImageSequences(dir): 
    seen = set() 
    for object in os.listdir(dir): 
     if os.path.isdir(dir + "\\" + str(object)): 
      find_all_ImageSequences(dir + "\\" + str(object)) 
     else: 
      if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')): 
       image_filename = object.split(".", 1)[0] 
       if image_filename not in seen: 
        Image_Sequences_List.append(dir + "\\" + str(object)) 
        seen.add(image_filename) 

:

많은 감사

+0

이미지 시퀀스 란 무엇입니까? 파일 세트? 어떤 파일이 같은 순서로 속해 있는지 어떻게 알 수 있습니까? –

+0

이 이미지 시퀀스는 무비 클립의 이미지 (프레임) 목록입니다. 이미지 시퀀스의 각 이미지는 같은 이름을 공유합니다 (예 : movie.001.jpg, movie.002.jpg, movie.003.jpg. 다른 이미지 시퀀스는 다음과 같습니다. holiday.001.jpg, holiday.002.jpg etc. – iGwok

답변

1

약간의 시간이 지나면 이것을 약화시키는 것이 가장 빠른 해결책이라는 것을 알게되었습니다.

def find_all_ImageSequences(dir): 

    child_directories = [x for x in os.listdir(dir) if len(x.split(".")) == 1] 
    if len(child_directories) >= 1: 
     for directory in child_directories: 
      if os.path.isdir(dir + "\\" + directory): 
       find_all_ImageSequences(dir + "\\" + directory) 

    for object in os.listdir(dir): 
     if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')): 
      image_filename = object.split(".")[0] 
      Image_Sequences_List.append(dir + "\\" + str(object)) 
      if any([x for x in os.listdir(dir) if x.split(".")[0] != image_filename and len(x.split(".")) > 1]): 
       extras = set([x.split(".")[0] for x in os.listdir(dir) if x.split(".")[0] != image_filename]) 
       for i in extras: 
        Image_Sequences_List.append(i) 
      break 

내가 표준 os.walk()이 기능을 비교하는 빠른 테스트했다 :

  • os.walk()를 5 초 걸렸습니다() 평균
  • find_all_ImageSequences 53 초 걸렸습니다 평균

다른 이미지 시퀀스가없는 경우이 속도는 주로 디렉토리를 벗어납니다. 도움을 준 Janne Karila에게 감사드립니다. set()을 사용하면 매우 유용합니다.

2

이 코드는 이미 추가 된 파일 이름을 추적하기 위해 세트를 사용 Windows에서 약 8-9 배, Linux 및 Mac OS X에서 약 2-3 배 빠르다 고 주장했습니다.

+0

나는 이것을 좋아하지만 여전히 시퀀스의 모든 이미지를 확인하지는 않습니까? 가능한 한 신속하게 1 개의 이미지를 찾은 다음 찾으려는 다른 이미지 시퀀스가없는 한 해당 디렉토리에서 벗어나고 싶습니다. 어쩌면 내가이 예와 관련하여 any() 문을 사용할 수 있습니다.어떻게 생각해? – iGwok

+0

@iGwok 디렉토리에 몇 개의 시퀀스가 ​​있는지 미리 모르는 경우 모든 파일 이름을 확인해야합니다. 어쩌면 마지막 하나가 단일 프레임 시퀀스입니다. –

+0

모든 이미지 파일을 반복하는 것보다이 작업을 더 빨리 처리 할 수 ​​있기를 바랍니다. 예를 들어 list comprehension을 사용하는 것은 for 루프를 사용하는 것보다 빠르며 any() 문은 디렉토리에있는 내용을 빠르게 분석하는 것처럼 보입니다. 이 속도를 높이는 데 도움이되는 다른 방법이 있습니까? 여기에는 속도가 핵심입니다. 덕분에 – iGwok