2012-08-07 24 views
0

我有一個圖像文件,我想檢查它是否使用python的圖像序列的一部分。最好的方式來確定圖像是否是序列的一部分

例如,我開始與這個文件:

/projects/image_0001.jpg 

,我要檢查,如果該文件是即

/projects/image_0001.jpg 
/projects/image_0002.jpg 
/projects/image_0003.jpg 
... 

檢查是否有圖像序列似乎是一個序列的一部分簡單如果我可以確定文件名是否可以是藝術的序列,即如果有一個數字序列的文件名

我的第一個雖然是要求用戶添加####添加到數字應該在的文件路徑中,並輸入開始和結束幀號以替換哈希值,但這顯然不是非常用戶友好的。有沒有辦法檢查正則表達式或類似的字符串中的數字序列?

+0

什麼是圖像序列?你能給個例子嗎? – Blender 2012-08-08 00:10:28

+0

是否所有文件名都以'picture_xxxx'的形式存在,或者是否有任何舊文件名混合? – 2012-08-08 00:36:58

+0

可能是pic.xxxx.jpg或pic-xxx.jpg等我想讓腳本儘可能靈活以解釋不同的人的喜好 – 2012-08-08 02:47:02

回答

2

使用python的re模塊來查看一個字符串是否包含數字序列相對容易。你可以這樣做:

mo = re.findall('\d+', filename) 

這將返回在filename所有數字序列的列表。如果:

  • 有一個單一的結果(即,文件名僅包含數字的單個序列),AND
  • 後續文件名具有相同的長度的單一的數字序列,並且
  • 的第二個數字序列比前一個數字大1

...然後可能它們是序列的一部分。

+0

如果你需要知道數字在字符串中的位置,你可以使用:'mo = list(re.finditer('\ d +',filename))',它將返回一個匹配對象列表,其中每個匹配對象都定義了方法'mo [i] .start()'和'mo [i ] .end關於()'。要獲取其中一個匹配對象的文本,請使用'mo [i] .group()'。有關匹配對象的更多信息,請參閱http://docs.python.org/library/re.html#match-objects。 – 2012-08-08 00:51:28

2

我假設問題更多的是能夠區分磁盤上的排序文件,而不是知道有關文件名本身的任何特定信息。

如果那的情況下,你正在尋找的是什麼東西,是足夠聰明採取類似的列表:

  • /path/to/file_1.png
  • /路徑/到/ file_2.png
  • /path/to/file_3.png
  • ...
  • /path/to/file_10.png
  • /path/to/image_1.png
  • /path/to/image_2.png
  • ...
  • /path/to/image_10.png

,並得到一個結果說 - 我有文件的2個序列:/路徑/到/file_#.png和/path/to/image_#.png你需要2遍 - 第一遍以確定文件的有效表達式,第二遍以找出所有其他文件滿足該要求。

你還需要知道,如果你要支持間隙(是按順序排列是必需的)

  • /path/to/file_1.png
  • /路徑/到/ file_2巴紐
  • /path/to/file_3.png
  • /path/to/file_5.png
  • /path/to/file_6.png
  • /path/to/file_7.png

這是1個序列(/path/to/file_#.png)或2個序列(/path/to/file_1-3.png,/path/to/file_5-7.png)

另外 - 你想如何處理序列中的數字文件?

  • /path/to/file2_1.png
  • /path/to/file2_2.png
  • /path/to/file2_3.png

隨着該記住,這是我將如何實現它:

import os.path 
    import projex.sorting 
    import re 

    def find_sequences(filenames): 
     """ 
     Parse a list of filenames into a dictionary of sequences. Filenames not 
     part of a sequence are returned in the None key 

     :param  filenames | [<str>, ..] 

     :return  {<str> sequence: [<str> filename, ..], ..} 
     """ 
     local_filenames = filenames[:] 
     sequence_patterns = {} 
     sequences   = {None: []} 

     # sort the files (by natural order) so we always generate a pattern 
     # based on the first potential file in a sequence 
     local_filenames.sort(projex.sorting.natural) 

     # create the expression to determine if a sequence is possible 
     # we are going to assume that its always going to be the 
     # last set of digits that makes a sequence, i.e. 
     # 
     # test2_1.png 
     # test2_2.png 
     # 
     # test2 will be treated as part of the name 
     # 
     # test1.png 
     # test2.png 
     # 
     # whereas here the 1 and 2 are part of the sequence 
     # 
     # more advanced expressions would be needed to support 
     # 
     # test_01_2.png 
     # test_02_2.png 
     # test_03_2.png 

     pattern_expr = re.compile('^(.*)(\d+)([^\d]*)$') 

     # process the inputed files for sequences 
     for filename in filenames: 
      # first, check to see if this filename matches a sequence 
      found = False 
      for key, pattern in sequence_patterns.items(): 
       match = pattern.match(filename) 
       if (not match): 
        continue 

       sequences[key].append(filename) 
       found = True 
       break 

      # if we've already been matched, then continue on 
      if (found): 
       continue 

      # next, see if this filename should start a new sequence 
      basename  = os.path.basename(filename) 
      pattern_match = pattern_expr.match(basename) 
      if (pattern_match): 
       opts = (pattern_match.group(1), pattern_match.group(3)) 
       key = '%s#%s' % opts 

       # create a new pattern based on the filename 
       sequence_pattern = re.compile('^%s\d+%s$' % opts) 

       sequence_patterns[key] = sequence_pattern 
       sequences[key] = [filename] 
       continue 

      # otherwise, add it to the list of non-sequences 
      sequences[None].append(filename) 

     # now that we have grouped everything, we'll merge back filenames 
     # that were potential sequences, but only contain a single file to the 
     # non-sequential list 
     for key, filenames in sequences.items(): 
      if (key is None or len(filenames) > 1): 
       continue 

      sequences.pop(key) 
      sequences[None] += filenames 

     return sequences 

而且一個例子Ë用法:

>>> test = ['test1.png','test2.png','test3.png','test4.png','test2_1.png','test2_2.png','test2_3.png','test2_4.png'] 
>>> results = find_sequences(test) 
>>> results.keys() 
[None, 'test#.png', 'test2_#.png'] 

有一種方法在那裏,是指天然排序,這是一個單獨的主題。我只是使用我的projex庫中的自然排序方法。它是開源的,所以如果你想使用或看到它,它的地址如下:http://dev.projexsoftware.com/projects/projex

但是這個話題已經在論壇的其他地方討論過了,所以剛剛使用了庫中的方法。

相關問題