2010-03-31 41 views
8

Tác vụ: Tôi có một camera được gắn ở cuối dây chuyền lắp ráp của chúng tôi, trong đó chụp ảnh các mặt hàng được sản xuất. Ví dụ: giả sử chúng tôi sản xuất vé (với một số văn bản và hình ảnh trên đó). Vì vậy, mỗi vé sản xuất được chụp ảnh và lưu vào đĩa dưới dạng hình ảnh. Bây giờ, tôi muốn kiểm tra những hình ảnh đã lưu này về các bất thường (ví dụ: so sánh chúng với hình ảnh (mẫu), điều này là OK). Vì vậy, nếu có sự cố với vé trên dây chuyền lắp ráp của chúng tôi (ảnh thiếu, vết bẩn, ...), ứng dụng của tôi sẽ tìm thấy nó (vì hình ảnh của nó khác quá nhiều so với mẫu ).So sánh hình ảnh để tìm sự khác biệt

Câu hỏi: Cách dễ nhất để so sánh hình ảnh và tìm sự khác biệt giữa các hình ảnh là gì? Tôi có cần phải viết các phương pháp của riêng mình hay tôi có thể sử dụng các phương pháp hiện có hay không ? Sẽ tuyệt vời nếu tôi chỉ đặt giá trị dung sai (tức là hình ảnh có thể khác nhau 1%), đặt cả hai hình ảnh vào một hàm và nhận giá trị trả lại là đúng hoặc sai :)

Công cụ: C# hoặc VB. NET, Emgu.CV (NET wrapper cho OpenCV) hoặc một cái gì đó tương tự

Trả lời

2

tôi d khuyên bạn nên xem AForge Imaging library vì nó có rất nhiều chức năng thực sự hữu ích trong đó cho loại công việc này.

Có một số phương pháp bạn có thể sử dụng:

  1. Simple trừ (mẫu hình ảnh - hiện tại) và xem có bao nhiêu điểm ảnh là khác nhau. Bạn có thể muốn chặn kết quả, nghĩa là chỉ bao gồm các pixel khác nhau 10 hoặc nhiều hơn (ví dụ).
  2. Nếu vé có thể di chuyển trong trường nhìn thì mục 1) sẽ không hoạt động trừ khi bạn có thể tìm vé trước. Ví dụ, nếu vé có màu trắng trên nền đen, bạn có thể làm một ngưỡng trên hình ảnh và điều đó sẽ cho bạn ý tưởng tốt về vị trí của vé.
  3. Một kỹ thuật khác mà tôi đã sử dụng trước đây là "Tìm mẫu" hoặc "Ghép mẫu", nhưng tôi chỉ biết một thư viện thương mại Matrox Imaging Library (hoặc MIL) có chứa các hàm này vì chúng không nhỏ.

Ngoài ra, bạn cần đảm bảo bạn biết phần nào của vé quan trọng hơn. Ví dụ tôi đoán rằng một logo hoặc hình mờ bị thiếu là một vấn đề lớn. Nhưng một số khu vực có thể có văn bản thay đổi, chẳng hạn như số sê-ri và vì vậy bạn mong muốn chúng khác nhau. Về cơ bản bạn có thể cần phải xử lý một số khu vực của hình ảnh khác với những người khác.

1

Tôi không biết chi tiết nhưng tôi biết rằng trong các tình huống công nghiệp, nơi thông lượng cao là điều thiết yếu đôi khi được thực hiện bằng cách sử dụng lưới thần kinh. Họ biến hàng triệu bit (pixel camera) thành 1 (tốt hay xấu). Có thể điều này sẽ giúp bạn tìm kiếm.

3

Tôi không biết nhiều về OpenCV, nhưng một chút về xử lý hình ảnh.

Cách di chuyển phụ thuộc vào tần suất trong ảnh mới được chụp. Một cách tiếp cận đơn giản sẽ là tính toán một hình ảnh khác biệt của bạn 'tốt' mẫu và hình ảnh của sản phẩm thực tế của bạn.

Nếu hình ảnh giống hệt nhau 100%, hình ảnh kết quả của bạn sẽ trống. Nếu có các pixel còn lại, bạn có thể đếm chúng và lấy chúng làm thước đo độ lệch so với tiêu chuẩn.

Tuy nhiên, bạn sẽ phải khớp với hướng (và có thể là tỷ lệ) của một trong các hình ảnh để căn chỉnh đường viền đó, nếu không cách tiếp cận này sẽ không hoạt động.

Nếu bạn có hạn chế về thời gian, bạn có thể muốn giảm thông tin trong hình ảnh trước khi xử lý chúng (ví dụ như phát hiện cạnh và/hoặc chuyển đổi chúng sang màu xám hoặc thậm chí bitmap đơn sắc nếu các tính năng của sản phẩm đủ quan trọng)

1

Chắc chắn có các ứng dụng và thư viện ngoài đó đã làm những gì bạn đang cố gắng làm, nhưng tôi không biết bất kỳ điều gì. Rõ ràng, người ta có thể băm hai hình ảnh và so sánh nhưng hy vọng mọi thứ sẽ là giống hệt nhau và không để lại bất kỳ sự thay đổi nào về sự khác biệt về ánh sáng hoặc những thứ tương tự.

Giả sử rằng bạn đã kiểm soát đối với các đối tượng trong hình ảnh được định hướng hệt và vị trí giống nhau, có một điều bạn thể làm là diễu qua các điểm ảnh của mỗi hình ảnh, và nhận được các giá trị HSV của mỗi như vậy:

Color color1 = Image1.GetPixel(i,j); 
Color color2 = Image2.GetPIxel(i,j); 
float hue1 = color1.GetHue(); 
float sat1 = color1.GetSaturation(); 
float bright1 = color1.GetBrightness(); 
float hue2 = color2.GetHue(); 
float sat2 = color2.GetSaturation(); 
float bright2 = color2.GetBrightness(); 

và thực hiện một số so sánh với các giá trị đó. Điều đó sẽ cho phép bạn so sánh chúng, tôi nghĩ rằng, với độ tin cậy cao hơn so với sử dụng các giá trị RGB, đặc biệt là kể từ khi bạn muốn bao gồm một số dung sai trong so sánh của bạn.


Edit:

Chỉ cần cho vui, tôi đã viết một ứng dụng mẫu nhỏ mà sử dụng ý tưởng của tôi ở trên. Về cơ bản, tổng số điểm ảnh có giá trị H, S và V khác nhau bởi một số tiền (tôi đã chọn 0,1 làm giá trị của mình) và sau đó loại bỏ các vòng so sánh nếu các bộ đếm H, S hoặc V vượt quá 38400 hoặc 2% các pixel (0,02 * 1600 * 1200). Trong trường hợp xấu nhất, mất khoảng 2 giây để so sánh hai hình ảnh giống nhau. Khi tôi so sánh những hình ảnh mà một người đã được thay đổi đủ để vượt quá giá trị 2% đó, nó thường mất một phần nhỏ của một giây.

Rõ ràng, điều này có thể sẽ quá chậm nếu có rất nhiều hình ảnh được tạo ra mỗi giây, nhưng tôi nghĩ điều đó thật thú vị.

+0

Việc băm nhỏ là một ý tưởng hay, nhưng phân tích pixel theo điểm ảnh sẽ không mang lại hiệu suất tối ưu do số lượng pixel tối đa cho mỗi hình ảnh (nghĩ 1600 * 1200 byte hoặc 1,875 MB trong thang độ xám) – sum1stolemyname

+0

như nó phụ thuộc vào tốc độ của thuật toán được sử dụng, vì bất kỳ thuật toán nào được kỳ vọng nhận ra sự khác biệt trên 1-2% sẽ phải lặp lại toàn bộ tệp. Có thể thực hiện phép trừ nhanh các hình ảnh, sau đó cộng lại số dư. Đó sẽ là nhanh như bạn có thể làm cho nó trong khi vẫn kiểm tra toàn bộ hình ảnh. – tloflin

1

This guy here đã viết một mã Java đơn giản cho cùng một vấn đề. Nó sẽ không khó để chuyển nó sang C#, tôi đoán vậy. Nó hoạt động tốt, cũng có thể tìm thấy phiên bản mới hơn và mạnh hơn trong đó.

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