2011-12-31 16 views
6

Tôi đang chụp ảnh màn hình của màn hình bằng rô-bốt và sau đó tìm kiếm các hình ảnh nhỏ hơn trong các ảnh chụp màn hình đó. Điều này hoạt động trên Windows nhưng không phải OS X do hiệu chỉnh gamma. Giải pháp tốt nhất tôi có thể đưa ra là chỉ đơn giản là phù hợp với màu sắc tương tự thay vì kết hợp màu sắc chính xác.Cách đối sánh các màu tương tự trong Java bằng cách sử dụng getRGB

Nỗi sợ của tôi là phù hợp với màu tương tự sẽ có nghĩa là vượt quá getRGB do đó sẽ làm chậm chương trình của tôi (vì nó chụp nhiều ảnh chụp màn hình và so sánh chúng với hình ảnh nhỏ hơn để tìm kiếm kết quả rất nhanh).

Câu hỏi của tôi là, cho phép nói tôi đã BufferedImage Ảnh chụp màn hình và BufferedImage smallImage, làm thế nào tôi sẽ đi về việc xác định nếu Screenshot.getRGB (1,1) và smallImage.getRGB (1,1) là tương tự màu sắc?

+0

bạn hỏi trong một chú thích về một cách nhanh hơn để có được giá trị pixel hơn * getRGB * ... * getRGB * có thể thực sự được khủng khiếp chậm: trên một số phiên bản OS X, nó có thể lên đến hai đơn đặt hàng độ lớn (yup, một trăm lần chậm hơn [!], được đo trên OS X 10.4) chậm hơn so với trực tiếp nhận được các giá trị pixel từ cơ bản * int [] *. Xem câu trả lời của tôi (được chấp nhận) ở đây về cách nhanh hơn để trích xuất một biểu đồ từ một hình ảnh: http://stackoverflow.com/questions/8218072/faster-way-to-extract-histogram-from-an-image/8218570#8218570 Một kỹ thuật tương tự có thể được áp dụng trong trường hợp của bạn để cả hai nhanh hơn và tránh hiệu chỉnh gamma. – TacticalCoder

Trả lời

4

Có một giấy thú vị về chính xác những vấn đề này:

Một New perceptually Uniform Không gian màu với Associated Màu tương đồng Measure cho nội dung dựa trên hình ảnh và video Retrieval bởi M. Sarifuddin và Rokia Missaoui

Bạn có thể tìm thấy điều này dễ dàng sử dụng Google hoặc đặc biệt Google Scholar.

Để tóm tắt, một số không gian màu (ví dụ: RGB, HSV, Lab) và các biện pháp khoảng cách (chẳng hạn như trung bình hình học và khoảng cách Euclide) là đại diện tốt hơn về nhận thức của con người về sự giống nhau về màu sắc so với các phương pháp khác. Bài báo nói về một không gian màu mới, tốt hơn so với phần còn lại, nhưng nó cũng cung cấp một sự so sánh tốt về các không gian màu hiện có chung và các biện pháp khoảng cách. Về mặt chất lượng *, có vẻ như biện pháp tốt nhất cho khoảng cách nhận thức bằng cách sử dụng các không gian màu phổ biến là: không gian màu HSV và thước đo khoảng cách hình trụ.

* Ít nhất, theo Hình 15 trong giấy được tham chiếu.

Thước đo khoảng cách trụ là (theo ký hiệu Latex):

D_ {cyl} = \ sqrt {\ Delta V^{2} + S_1^{2} + S_2^{2} -2S_1S_2cos (\ Delta H)}

Cũng lưu ý có một số câu hỏi tương tự mà giải quyết cùng một vấn đề:

finding similar colors programatically

"Distance" between colours in PHP

Cuối cùng, trong J ava, có cách nào dễ dàng để chuyển đổi từ giá trị RGB vào không gian màu khác:

ColorSpace.fromRGB

1

Đối với tương đồng màu sắc, chúng ta hãy DR=R1-R2, DG=G1-G2, DB=B1-B2, sau đó tính toán DR×DR+DG×DG+DB×DB và lấy căn bậc hai của đó, và so sánh nó với một số giá trị ngưỡng. Tất nhiên, điều này có thể được tối ưu hóa đơn giản bằng cách bỏ qua phần căn bậc hai và chỉ cần bình phương ngưỡng. Tuy nhiên, bạn có thể tốt hơn nếu bạn quản lý bằng cách nào đó để OSX hiển thị PNG chứa hình ảnh của bạn trên màn hình, sau đó đọc phần đó của màn hình và sau đó tìm kiếm kết quả khớp chính xác với hình ảnh đó.

+0

Của bạn là một ý nghĩa hình học, tôi nghĩ vậy. Làm thế nào là tốt hơn so với việc sử dụng tính toán khoảng cách Euclide? Trong mã giả, 'sqrt (sqr (r1-r2) + sqr (g1-g2) + sqr (b1-b2))' –

+0

Tha thứ cho tôi để hỏi, nhưng có cách nào hiệu quả hơn để lấy giá trị RGB của tọa độ pixel khác không hơn là phá vỡ nó sau khi gọi getRGB()? Tôi rất muốn biết cách cấu hình captureScreen trong rô-bốt để hiển thị chính xác ảnh chụp màn hình OS X với hiệu chỉnh gamma tốt hơn tương tự như Windows, nhưng tôi không biết cách thực hiện điều này. – Macmee

+0

@HovercraftFullOfEels damn Alzheimer's. Tôi sẽ sửa câu trả lời của tôi. –

0

bạn đang sử dụng this Phương pháp getRGB? Nếu có, tôi sẽ so sánh các phần tử mảng 1 đến 3 (RGB) với nhau bằng cách trừ chúng và kiểm tra xem giá trị tuyệt đối của giá trị này có thấp hơn ngưỡng đã cho hay không (ví dụ: 10). Vì vậy, nó sẽ là một cái gì đó giống như

if(Math.abs(firstPixel[1]-secondPixel[1])<10) 
    redIsSimilar = true; 
else 
    redIsSimilar=false; 

mà không cần lệnh if:

redIsSimilar = Math.abs(firstPixel[1]-secondPixel[1]) < 10; 

Tất nhiên bạn cần phải sao chép dán này cho màu xanh lá cây và màu xanh là tốt. Hope this helps, Christoph

+0

Tôi đang sử dụng getRGB của lớp BufferedImage tại đây http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html#getRGB(int, int) – Macmee