5

Tôi có 110 tệp PDF mà tôi đang cố trích xuất hình ảnh. Khi hình ảnh được trích xuất, tôi muốn xóa mọi bản sao và xóa hình ảnh có kích thước nhỏ hơn 4KB. Mã của tôi để làm điều đó trông giống như sau:Làm thế nào để sử dụng đúng mô-đun đa xử lý trong Python?

def extract_images_from_file(pdf_file): 
    file_name = os.path.splitext(os.path.basename(pdf_file))[0] 
    call(["pdfimages", "-png", pdf_file, file_name]) 
    os.remove(pdf_file) 

def dedup_images(): 
    os.mkdir("unique_images") 
    md5_library = [] 
    images = glob("*.png") 
    print "Deleting images smaller than 4KB and generating the MD5 hash values for all other images..." 
    for image in images: 
     if os.path.getsize(image) <= 4000: 
      os.remove(image) 
     else: 
      m = md5.new() 
      image_data = list(Image.open(image).getdata()) 
      image_string = "".join(["".join([str(tpl[0]), str(tpl[1]), str(tpl[2])]) for tpl in image_data]) 
      m.update(image_string) 
      md5_library.append([image, m.digest()]) 
    headers = ['image_file', 'md5'] 
    dat = pd.DataFrame(md5_library, columns=headers).sort(['md5']) 
    dat.drop_duplicates(subset="md5", inplace=True) 

    print "Extracting the unique images." 
    unique_images = dat.image_file.tolist() 
    for image in unique_images: 
     old_file = image 
     new_file = "unique_images\\" + image 
     shutil.copy(old_file, new_file) 

Quá trình này có thể mất một lúc, vì vậy tôi đã bắt đầu dabble đa luồng. Hãy giải thích rằng khi tôi nói tôi không biết mình đang làm gì. Tôi nghĩ rằng quá trình sẽ dễ dàng song song đối với việc trích xuất các hình ảnh, nhưng không deduping vì có rất nhiều I/O đang xảy ra với một tập tin và tôi không có ý tưởng làm thế nào để làm điều đó. Vì vậy, đây là nỗ lực của tôi trong quy trình song song:

if __name__ == '__main__': 
    filepath = sys.argv[1] 
    folder_name = os.getcwd() + "\\all_images\\" 
    if not os.path.exists(folder_name): 
     os.mkdir(folder_name) 
    pdfs = glob("*.pdf") 
    print "Copying all PDFs to the images folder..." 
    for pdf in pdfs: 
     shutil.copy(pdf, ".\\all_images\\") 
    os.chdir("all_images") 
    pool = Pool(processes=8) 
    print "Extracting images from PDFs..." 
    pool.map(extract_images_from_file, pdfs) 
    print "Extracting unique images into a new folder..." 
    dedup_images() 
    print "All images have been extracted and deduped." 

Mọi thứ dường như đã hoạt động tốt khi trích xuất hình ảnh, nhưng sau đó tất cả đều có kết nối. Vì vậy, đây là câu hỏi của tôi:

1) Tôi có đang thiết lập đúng quy trình song song không?
2) Có tiếp tục sử dụng tất cả 8 bộ vi xử lý trên dedup_images() không?
3) Có bất kỳ điều gì tôi thiếu và/hoặc không hoạt động chính xác không?

Cảm ơn trước!

EDIT Đây là ý nghĩa của từ "haywire". Các lỗi bắt đầu với một loạt các dòng như thế này:

I/O Error: Couldn't open image If/iOl eE r'rSourb:p oICe/onOua l EdNrner'wot r Y:oo prCekon u Cliodmunan'gttey of1pi0e 
l2ne1 1i'4mS auogbiepl o2fefinrlaee e [email protected]'egSwmu abYipolor ekcn oaCm o Nupentwt y1Y -o18r16k11 8.C1po4nu gn3't4 
y7 5160120821143 3p4t7I 9/49O-8 88E78r81r.3op rnp:gt ' C 
3o-u3l6d0n.'ptn go'p 
en image file 'Ia/ ON eEwr rYoorr:k CCIoo/uuOln dtEnyr' rt1o 0ro2:p1 e1Cn4o uiolmidalng2'eft r m ' 
ai gpceoo emfn iapl teN e1'w-S 8uY6bo2pr.okpe nnCgao' u 
Nnetwy Y1o0r2k8 1C4o u3n4t7y9 918181881134 3p4t7 536-1306211.3p npgt' 
4-879.png' 
I/O Error: CoulId/nO' tE rorpoern: iCmoaugled nf'itl eo p'eub piomeangae fNielwe Y'oSrukb pCooeunnat yN e1w0 2Y8o1r 
4k 3C4o7u9n9t8y8 811032 1p1t4 3o-i3l622f pt 1-863.png' 

Và sau đó trở nên dễ đọc hơn với nhiều dòng như thế này:

I/O Error: Couldn't open image file 'pt 1-864.png' 
I/O Error: Couldn't open image file 'pt 1-865.png' 
I/O Error: Couldn't open image file 'pt 1-866.png' 
I/O Error: Couldn't open image file 'pt 1-867.png' 

này lặp đi lặp lại trong một thời gian, đi lại giữa các bị cắt xén văn bản lỗi và có thể đọc được.

Cuối cùng, nó được để ở đây:

Deleting images smaller than 4KB and generating the MD5 hash values for all other images... 
Extracting unique images into a new folder... 

trong đó hàm ý rằng mã chọn sao lưu và tiếp tục trên với quá trình này. Điều gì có thể xảy ra?

+1

Điều đó có vẻ ổn với tôi. Bạn có thể cụ thể hơn về "đi haywire"? – strubbly

+0

@strubbly Tôi đã thêm đầu ra lỗi ở trên. – brittenb

+0

"Tôi đã bắt đầu dabble trong đa luồng. Cảm thấy tự do để giải thích rằng khi tôi nói tôi không có ý tưởng những gì tôi đang làm" Bạn và tất cả những người khác bắt đầu làm việc với concurrency. –

Trả lời

3

Mã của bạn về cơ bản là tốt.

Văn bản bị cắt xén là tất cả các quá trình cố gắng viết các phiên bản khác nhau của thông báo I/O Error xen kẽ vào bảng điều khiển. Thông báo lỗi đang được tạo ra bởi lệnh pdfimages, có thể vì khi bạn chạy hai cùng một lúc, chúng xung đột, có thể trên các tệp tạm thời hoặc cả hai đều sử dụng cùng tên tệp hoặc giống như vậy.

Thử sử dụng gốc hình ảnh khác cho từng tệp pdf riêng biệt.

+0

Tôi đã chấp nhận điều này như là câu trả lời vì nó đã giải quyết được vấn đề tôi đang gặp phải một cách hiệu quả. Tôi nối thêm một chữ số gồm 3 chữ số ngẫu nhiên vào tên gốc và nó hoàn toàn làm giảm bớt bất kỳ vấn đề nào. Cảm ơn! – brittenb

+0

Tuyệt vời - bạn đang làm tốt với việc xử lý đa - chỉ cần nhớ rằng những thứ bạn gọi cần có khả năng chạy cùng nhau. Họ có thể xung đột khi họ chia sẻ tài nguyên như thư mục hoặc tệp. – strubbly

3
  1. Có, Pool.map lấy một hàm lấy 1 đối số và sau đó là danh sách, mỗi phần tử được chuyển làm đối số cho hàm đầu tiên.
  2. Không, bởi vì mọi thứ bạn đã viết ở đây đều chạy trong quy trình gốc ngoại trừ phần thân của extract_images_from_file(). Ngoài ra, tôi sẽ chỉ ra rằng bạn đang sử dụng 8 quy trình, không phải là bộ vi xử lý. Nếu bạn tình cờ có CPU Intel 8 lõi, với tính năng Siêu phân luồng được bật, bạn có thể chạy đồng thời 16 quy trình.
  3. Có vẻ ổn với tôi, ngoại trừ việc, nếu extract_images_from_file() ném ngoại lệ, nó sẽ nuke toàn bộ số Pool của bạn, có lẽ không phải là những gì bạn muốn. Để ngăn chặn điều này, bạn có thể đặt thử quanh khối đó.

Bản chất của "haywire" bạn đang xử lý là gì? Chúng tôi có thể xem văn bản ngoại lệ không?

+0

Tôi đã thêm đầu ra lỗi cho câu hỏi. – brittenb

Các vấn đề liên quan