Tìm ảnh trùng nhau bằng VBA

Liên hệ QC

MỹHạnhCB

Đi mây, về gió. !!!
Tham gia
25/3/22
Bài viết
123
Được thích
18
Chào các anh chị trong diễn đàn GPE.
Em muốn hỏi là trong VBA có thuật toán chạy kiểm tra hình ảnh giống nhau không ạ? Nếu có, có thể có em xin để tham khảo ạ. Em xin cảm ơn nhiều.
"Theo như yêu cầu là chạy thư mục chứa ảnh (1) -> So sánh ảnh trong thư mục (1) -> Phát hiện từ ảnh 2,3,4 bị trùng (giống nhau) -> Báo cáo kết quả ra Excel"
 

File đính kèm

  • 1.zip
    5.4 MB · Đọc: 34
Bạn chạy thử rồi cho tôi (và tiện thể cho tác giả của bài #52) biết là tổng số file ảnh đã được duyệt qua là bao nhiêu và thời gian chạy khoảng bao nhiêu giây.
Hiện em chạy thử trên 1200 ảnh (6,5mb/1 ảnh) chạy tầm 3 phút. Lọc được 220 ảnh trùng nhau.
Còn nguồn gốc (>20000 ảnh (2mb/1 ảnh) đợi em test xong em báo lại sau ạ.
 
Upvote 0
Hiện em chạy thử trên 1200 ảnh (6,5mb/1 ảnh) chạy tầm 3 phút. Lọc được 220 ảnh trùng nhau.
Còn nguồn gốc (>20000 ảnh (2mb/1 ảnh) đợi em test xong em báo lại sau ạ.
Vậy là tốt đó chứ. Vậy mà bài #52 nói chạy treo máy luôn
 
Upvote 0
Vậy là tốt đó chứ. Vậy mà bài #52 nói chạy treo máy luôn
Hôm qua, tôi có thử tạo ra một script nhỏ chạy 1000 vòng (tương ứng 1000 file) với một file ảnh 882k để kiểm tra. Kết quả là hết 10s và tôi thấy cái điểm chuột quay vòng vòng cùng tiếng rú của quạt CPU. Vậy theo Maika8008 với hơn 20,000 ảnh 2mb (gấp 2,3 lần file thử nghiệm của tôi) thì máy tôi sẽ ngốn bao nhiêu thời gian và liệu nó có ngủm vì quá nhiệt CPU không?

Phân tích hiệu năng của 2 hàm GetFileBytes và FileToMD5Hex, và dù tiên đoán là FileToMD5Hex sẽ ngốn rất nhiều công lực nhưng tôi vẫn phải bất ngờ khi biết cái hàm FileToMD5Hex chiếm khoảng 80% thời gian thực thi. Và điều bất ngờ thứ 2 là nếu nạp vô hàm ComputeHash_2() 882k byte dữ liệu thì nó cho ra 20 byte dữ liệu và các bạn đem 20 byte này để xác định tính duy nhất của một file. Liệu có ai dám khẳng định là 20 byte kết xuất này sẽ đặc trưng cho một file hay là sẽ có một file khác cũng có chung 20 byte này sau khi nạp vô ComputeHash_2()?
 
Lần chỉnh sửa cuối:
Upvote 0
Hôm qua, tôi có thử tạo ra một script nhỏ chạy 1000 vòng (tương ứng 1000 file) với một file ảnh 882k để kiểm tra. Kết quả là hết 10s và tôi thấy cái điểm chuột quay vòng vòng cùng tiếng rú của quạt CPU. Vậy theo Maika8008 với hơn 20,000 ảnh 2mb (gấp 2,3 lần file thử nghiệm của tôi) thì máy tôi sẽ ngốn bao nhiêu thời gian và liệu nó có ngủm vì quá nhiệt CPU không?

Phân tích hiệu năng của 2 hàm GetFileBytes và FileToMD5Hex, và dù tiên đoán là FileToMD5Hex sẽ ngốn rất nhiều hiệu năng nhưng tôi vẫn phải bất ngờ khi biết cái hàm FileToMD5Hex chiếm khoảng 80% thời gian thực thi. Và điều bất ngờ thứ 2 là nếu nạp vô hàm ComputeHash_2() 882k byte dữ liệu thì nó cho ra 20 byte dữ liệu và các bạn đem 20 byte này để xác định tính duy nhất của một file. Liệu có ai dám khẳng định là 20 byte kết xuất này sẽ đặc trưng cho một file hay là sẽ có một file khác cũng có chung 20 byte này?
Dạ em chạy thì điểm chuột quay vòng và cũng có nghe quạt cpu quay. Còn những phân tích của anh thì em không chuyên nên em không bàn đến. Nhưng xử lý về công việc của em thì đây cũng coi là giải pháp rồi á anh. Các anh có cách nào tối ưu thêm thì tốt quá ạ.:p
 
Upvote 0
à em mới mò được cách là giảm dung lượng của ảnh xuống và chạy thì nhanh hơn đó 2 anh (từ 6.5mb/1 ảnh xuống còn 6.5kb/1 ảnh).
Thôi thì em chịu khó nén ảnh xuống rồi chạy mã sau vậy :)
 
Upvote 0
Hôm qua, tôi có thử tạo ra một script nhỏ chạy 1000 vòng (tương ứng 1000 file) với một file ảnh 882k để kiểm tra. Kết quả là hết 10s và tôi thấy cái điểm chuột quay vòng vòng cùng tiếng rú của quạt CPU. Vậy theo Maika8008 với hơn 20,000 ảnh 2mb (gấp 2,3 lần file thử nghiệm của tôi) thì máy tôi sẽ ngốn bao nhiêu thời gian và liệu nó có ngủm vì quá nhiệt CPU không?

Phân tích hiệu năng của 2 hàm GetFileBytes và FileToMD5Hex, và dù tiên đoán là FileToMD5Hex sẽ ngốn rất nhiều công lực nhưng tôi vẫn phải bất ngờ khi biết cái hàm FileToMD5Hex chiếm khoảng 80% thời gian thực thi. Và điều bất ngờ thứ 2 là nếu nạp vô hàm ComputeHash_2() 882k byte dữ liệu thì nó cho ra 20 byte dữ liệu và các bạn đem 20 byte này để xác định tính duy nhất của một file. Liệu có ai dám khẳng định là 20 byte kết xuất này sẽ đặc trưng cho một file hay là sẽ có một file khác cũng có chung 20 byte này sau khi nạp vô ComputeHash_2()?
Băm MD5 hoặc SHA1 là 1 giải thuật đã được kiểm chứng và dùng rộng rãi. Bạn có thể không tin vào nó nhưng nó vẫn được dùng để làm nền tảng cho chữ ký số trên 1 văn bản điện tử.
 
Upvote 0
Băm MD5 hoặc SHA1 là 1 giải thuật đã được kiểm chứng và dùng rộng rãi. Bạn có thể không tin vào nó nhưng nó vẫn được dùng để làm nền tảng cho chữ ký số trên 1 văn bản điện tử.
Trước tiên phải cám ơn bạn đã giải thích cho tôi hiểu thêm về chức năng của hàm này nhưng vấn đề quan tâm nhất của tôi là nếu thực hiện với dữ liệu thực tế trên máy của tôi thì sẽ mất bao lâu thì vẫn chưa có câu trả lời(?).
 
Upvote 0
Trước tiên phải cám ơn bạn đã giải thích cho tôi hiểu thêm về chức năng của hàm này nhưng vấn đề quan tâm nhất của tôi là nếu thực hiện với dữ liệu thực tế trên máy của tôi thì sẽ mất bao lâu thì vẫn chưa có câu trả lời(?).
Đoán nhé:
Máy của chủ thớt chạy 1200 ảnh cỡ 6.5MB thì mất tầm 3 phút. Các máy bây giờ không chênh nhau lắm về cấu hình. Nếu chậm lắm thì máy bạn chạy với chừng đó file mất tối đa 5 phút.

Tôi làm thầy bói mù đấy __--__
 
Upvote 0
Đoán nhé:
Máy của chủ thớt chạy 1200 ảnh cỡ 6.5MB thì mất tầm 3 phút. Các máy bây giờ không chênh nhau lắm về cấu hình. Nếu chậm lắm thì máy bạn chạy với chừng đó file mất tối đa 5 phút.
Tôi chạy mô phỏng 1000 lần trên một file 2.19MB trong điều kiện không mở bất cứ ứng dụng nào khác thì hết 10s. Còn nếu có bật app Opera thì thời gian dao động trong khoảng 12-19s. Vậy thì với hơn 30.000 file thì hết ước chừng hết khoảng 310s với điều kiện không có ứng dụng nào khác được mở và CPU được giữ ổn định nhiệt.

Tuy nhiên tôi lại phát hiện ra một tình huống vô cùng lý thú. Theo anh chủ topic, 2 file trùng nhau nhưng kích thước có thể lệch nhau một số byte. Vậy thì kết quả hàm băm của 2 file này giống hay khác nhau?
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi chạy mô phỏng 1000 lần trên một file 2.19MB trong điều kiện không mở bất cứ ứng dụng nào khác thì hết 10s. Còn nếu có bật app Opera thì thời gian dao động trong khoảng 12-19s. Vậy thì với hơn 30.000 file thì hết ước chừng hết khoảng 310s với điều kiện không có ứng dụng nào khác được mở và CPU được giữ ổn định nhiệt.

Tuy nhiên tôi lại phát ra một tình huống vô cùng lý thú. Theo anh chủ topic, 2 file trùng nhau nhưng kích thước có thể lệch nhau một số byte. Vậy thì kết quả hàm băm của 2 file này giống hay khác nhau?
2. Nếu hình quá nhiều như trường hợp của chủ thớt thì không nên ép Excel mà chia folder ra thành nhiều folder con để chạy.
3. Hai file hình nhìn thì trùng nhau nhưng chỉ cần khác nhau 1 pixel vào đó thì kết quả băm cũng đã khác nhau rồi. Bạn cứ thử băm 1 file Word, rồi mở file ấy thêm 1 dấu cách bất kỳ chỗ nào, lưu file rồi băm lại và so sánh 2 cái mã băm xem có khác nhau hoàn toàn không.
 
Upvote 0
Upvote 0
2. Nếu hình quá nhiều như trường hợp của chủ thớt thì không nên ép Excel mà chia folder ra thành nhiều folder con để chạy.
3. Hai file hình nhìn thì trùng nhau nhưng chỉ cần khác nhau 1 pixel vào đó thì kết quả băm cũng đã khác nhau rồi. Bạn cứ thử băm 1 file Word, rồi mở file ấy thêm 1 dấu cách bất kỳ chỗ nào, lưu file rồi băm lại và so sánh 2 cái mã băm xem có khác nhau hoàn toàn không.
Tôi tiếp tục phát hiện ra 2 vấn đề trong luận điểm Maika8008 ở đây:
  1. Maika8008 có dự tính được tính huống 2 file giống nhau lại được chia ra nằm ở 2 folder khác nhau và dẫn đến là chúng bị bỏ lọt vì không được đối chiếu không nhỉ?
  2. Nếu 2 file ảnh trùng nhau nhưng chỉ sai khác một vài byte thì bằng phép so sánh với hàm băm chúng bị coi là khác nhau (không trùng) và cũng lọt qua phép sàng lọc.
Tóm lại theo phương án dùng hàm băm:
  1. Để cải thiện trải nghiệm (nhưng không cải thiện được hiệu năng) thì phải chấp nhận sai số.
  2. Vì hàm băm dùng phép so sánh tuyệt đối nên bỏ sót những file trùng nhau nhưng sai khác vài byte tức là vẫn có sai số.
Nghĩa là sau khi chạy xong theo phương án Maika8008 nêu ra, thì anh chủ topic sẽ lại phải dùng phương pháp thủ công để đối chiếu trong mấy chục ngàn file để tìm ra số file trùng lắp bị bỏ sót. Và phương pháp thủ công hiệu quả nhất thì chắc là của tôi rồi nhưng vẫn khá tốn cơm và mỏi mắt đấy --=0 Còn không thì phải dùng app chẳng hạn như ACD... gì đấy
 
Upvote 0
Đúng như bạn Maika8008 đã nói, đối với hàm băm MD5 thì khác 1 byte cũng sẽ cho kết quả khác nhau. Và cũng có trường hợp 2 file khác nhau hoàn toàn nhưng có cùng MD5 hash và trường hợp này tỷ lệ vô cùng hiếm. Và cũng có trường hợp 2 MD5 hash giống nhau nhưng file khác nhau, các chuyên gia hack đã làm được. Do đó bây giờ muốn bảo mật cao hơn nữa thì dùng SHA 256. Tuy "nhiên trong trường hợp tìm file trùng này thì hàm MD5 đã quá đủ để dùng rồi.

Nhắc với bạn chủ thớt là so sánh dùng "Size on Disk" là không chính xác nhé, file size là chính xác nhất . Size on disk tùy thuộc vào việc phân chia kích thước vùng nhớ tối thiểu (Allocation unit) của hệ điều hành áp dụng cho một kiểu định dạng ổ cứng nào đó. Thông thường Windows sẽ phân bổ tối thiếu 4096 bytes (trên máy Mac tôi cũng vậy)

Screen Shot 2022-04-12 at 11.07.00.png

Nếu định dạng khác sẽ có kích thước khác: exFAT

Screen Shot 2022-04-12 at 11.08.33.png

Ví dụ: lấy từ cái hình chủ thớt đưa lên.

Screen Shot 2022-04-12 at 12.25.09.png

1 file có Size: 1.313.046 bytes, file kế có size: 1.313.064 --> khác nhau 18 bytes nhưng Size on Disk lại bằng nhau?
- File 1: nếu được phân bổ 320 units trên ổ cứng (để lưu) x 4096 = 1.310.720 bytes --> không đủ chứa file 1 <=> Windows sẽ cấp 321 units x 4096 = 1.314.816 bytes.
- File 2: tương tự 320 units cũng không đủ chứa nên được phân bổ 321 units ổ cứng <=> dung lượng Size on Disk như nhau.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi tiếp tục phát hiện ra 2 vấn đề trong luận điểm Maika8008 ở đây:
  1. Maika8008 có dự tính được tính huống 2 file giống nhau lại được chia ra nằm ở 2 folder khác nhau và dẫn đến là chúng bị bỏ lọt vì không được đối chiếu không nhỉ?
  2. Nếu 2 file ảnh trùng nhau nhưng chỉ sai khác một vài byte thì bằng phép so sánh với hàm băm chúng bị coi là khác nhau (không trùng) và cũng lọt qua phép sàng lọc.
Tóm lại theo phương án dùng hàm băm:
  1. Để cải thiện trải nghiệm (nhưng không cải thiện được hiệu năng) thì phải chấp nhận sai số.
  2. Vì hàm băm dùng phép so sánh tuyệt đối nên bỏ sót những file trùng nhau nhưng sai khác vài byte tức là vẫn có sai số.
Nghĩa là sau khi chạy xong theo phương án Maika8008 nêu ra, thì anh chủ topic sẽ lại phải dùng phương pháp thủ công để đối chiếu trong mấy chục ngàn file để tìm ra số file trùng lắp bị bỏ sót. Và phương pháp thủ công hiệu quả nhất thì chắc là của tôi rồi nhưng vẫn khá tốn cơm đấy --=0
Vấn đề 1: Tạm thời tôi chưa có phương án chia ra chạy, rồi gộp lại chạy tiếp thế nào để khỏi bỏ sót nhưng nếu là dữ liệu của tôi thì tôi sẽ tìm ra, vì: tôi sẽ biết dữ liệu hình của tôi trùng vì lý do gì, khác folder con thì có trùng không... và cuối cùng là tôi có động cơ để đầu tư suy nghĩ.
Vấn đề 2: Trên thực tế làm gì ai đem ra hình ra thêm 1 dấu chấm Save As lại rồi cho đó là hình trùng nhau được. Đã sửa 1 tí là phải xem là hình khác rồi. Hình trùng khi ai đó đem nhân bản ra trên máy tính thôi.
 
Upvote 0
Vấn đề 1: Tạm thời tôi chưa có phương án chia ra chạy, rồi gộp lại chạy tiếp thế nào để khỏi bỏ sót nhưng nếu là dữ liệu của tôi thì tôi sẽ tìm ra, vì: tôi sẽ biết dữ liệu hình của tôi trùng vì lý do gì, khác folder con thì có trùng không... và cuối cùng là tôi có động cơ để đầu tư suy nghĩ.
Thực ra vấn đề này cũng chỉ là thêm code, thêm bước để xử lý thôi và chắc chắn là nó sẽ làm chậm đi tiến trình.

Screen Shot 2022-04-12 at 13.01.29.png


Dùng MD5 để tìm các file giống nhau hoàn toàn. Nó cũng dùng được để tìm file ảnh nhưng chỉ là tương đối như bài #57 tôi đã đề cập. Muốn xác định file ảnh trùng theo tiêu chí gì, thuật toán nó sẽ phức tạp hơn chứ không đơn giản là so sánh 1 với 1.
Tôi có đính kèm 3 file ảnh: 21.jpg, 22.jpg, 23.jpg. Ba file nhìn bình thường sẽ rất giống nhau.
Tôi chỉ nâng sánh 1 đơn vị cho file 22.jpg nhưng size nó đã khác nhau 2kb.
File 23.jpg có thêm con chó nhưng size nó chỉ tăng chừng 500 bytes
Do đó nếu so sánh size không thôi thì khó chính xác nếu theo tiêu chí: nội dung hình giống nhau.
 

File đính kèm

  • 21.jpg
    21.jpg
    186.6 KB · Đọc: 1
  • 22.jpg
    22.jpg
    187.3 KB · Đọc: 1
  • 23.jpg
    23.jpg
    187.1 KB · Đọc: 1
Lần chỉnh sửa cuối:
Upvote 0
Vấn đề 1: Tạm thời tôi chưa có phương án chia ra chạy, rồi gộp lại chạy tiếp thế nào để khỏi bỏ sót nhưng nếu là dữ liệu của tôi thì tôi sẽ tìm ra, vì: tôi sẽ biết dữ liệu hình của tôi trùng vì lý do gì, khác folder con thì có trùng không... và cuối cùng là tôi có động cơ để đầu tư suy nghĩ.
Vấn đề 2: Trên thực tế làm gì ai đem ra hình ra thêm 1 dấu chấm Save As lại rồi cho đó là hình trùng nhau được. Đã sửa 1 tí là phải xem là hình khác rồi. Hình trùng khi ai đó đem nhân bản ra trên máy tính thôi.
Với vấn đề 1 Maika8008 nêu thì nghĩa là phải trong "điều kiện lý tưởng" phù hợp với khả năng giải quyết của Maika8008 chứ với các tình huống hỗn độn thì sẽ ra sao nhỉ? Vấn đề thứ 2 là có sự sai khác một vài byte giữa 2 ảnh trùng nhau khiến việc sàng lọc bị sai sót và đây là nguyên do đáng kể khiến anh chủ topic bỏ phương án của tôi mà theo phương án của Maika8008. Tuy nhiên có vẻ phương án của Maika8008 cũng đang bị vấn đề này và chắc không có phương án khắc phục.

Nếu không ngại dư luận, anh chủ topic chắc phải quay lại phương án của tôi vì nó cho phép sai số. Và có một điều nữa là phương án của tôi vẫn rộng cửa nâng cấp để đạt độ chính xác tốt hơn nữa. Còn riêng về hiệu năng, tôi bảo đảm sẽ có sự kinh ngạc về thời gian thực thi so với con số ước lượng hơn 300s của code Maika8008 trên máy tôi hiện tại.
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng như bạn Maika8008 đã nói, đối với hàm băm MD5 thì khác 1 byte cũng sẽ cho kết quả khác nhau. Và cũng có trường hợp 2 file khác nhau hoàn toàn nhưng có cùng MD5 hash và trường hợp này tỷ lệ vô cùng hiếm. Và cũng có trường hợp 2 MD5 hash giống nhau nhưng file khác nhau, các chuyên gia hack đã làm được. Do đó bây giờ muốn bảo mật cao hơn nữa thì dùng SHA 256. Tuy "nhiên trong trường hợp tìm file trùng này thì hàm MD5 đã quá đủ để dùng rồi.

Nhắc với bạn chủ thớt là so sánh dùng "Size on Disk" là không chính xác nhé, file size là chính xác nhất . Size on disk tùy thuộc vào việc phân chia kích thước vùng nhớ tối thiểu (Allocation unit) của hệ điều hành áp dụng cho một kiểu định dạng ổ cứng nào đó. Thông thường Windows sẽ phân bổ tối thiếu 4096 bytes (trên máy Mac tôi cũng vậy)

View attachment 274327

Nếu định dạng khác sẽ có kích thước khác: exFAT

View attachment 274328

Ví dụ: lấy từ cái hình chủ thớt đưa lên.

View attachment 274330

1 file có Size: 1.313.046 bytes, file kế có size: 1.313.064 --> khác nhau 18 bytes nhưng Size on Disk lại bằng nhau?
- File 1: nếu được phân bổ 320 units trên ổ cứng (để lưu) x 4096 = 1.310.720 bytes --> không đủ chứa file 1 <=> Windows sẽ cấp 321 units x 4096 = 1.314.816 bytes.
- File 2: tương tự 320 units cũng không đủ chứa nên được phân bổ 321 units ổ cứng <=> dung lượng Size on Disk như nhau.
Vâng anh, em đã ngừng phương pháp so sánh bằng "size on disk" rồi ạ, Và đang xài hàm băm MD5.
Bài đã được tự động gộp:

Với vấn đề 1 Maika8008 nêu thì nghĩa là phải trong "điều kiện lý tưởng" phù hợp với khả năng giải quyết của Maika8008 chứ với các tình huống hỗn độn thì sẽ ra sao nhỉ? Vấn đề thứ 2 là có sự sai khác một vài byte giữa 2 ảnh trùng nhau khiến việc sàng lọc bị sai sót và đây là nguyên do đáng kể khiến anh chủ topic bỏ phương án của tôi mà theo phương án của Maika8008. Tuy nhiên có vẻ phương án của Maika8008 cũng đang bị vấn đề này và chắc không có phương án khắc phục.

Nếu không ngại dư luận, anh chủ topic chắc phải quay lại phương án của tôi vì nó cho phép sai số. Và có một điều nữa là phương án của tôi vẫn rộng cửa nâng cấp để đạt độ chính xác tốt hơn nữa. Còn riêng về hiệu năng, tôi bảo đảm sẽ có sự kinh ngạc về thời gian thực thi so với con số ước lượng hơn 300s của code Maika8008 trên máy tôi hiện tại.
Vâng mọi ý kiến đóng góp của các anh chị rất tuyệt vời ạ. Nhưng em đang tính nếu mình chạy hàm băm và hàm "size" sau đó so sánh nếu cả 2 cùng trùng nhau thì ==> ảnh đó trùng nhau, còn 1 trong 2 khác nhau thì là khác nhau. Không biết có được không ạ. Mong anh chị góp ý thêm
Bài đã được tự động gộp:

Còn nếu excel dừng lại ở đó thì em xin phép anh maika8008 ở bài #63 có thể làm thêm ở (tool .exe của python tìm ảnh trùng và báo(xuất) ra file excel) để em có thể kiểm tra được không ạ. Cảm ơn a nhiều
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom