Thuật toán tô màu danh sách bài hát trong iTunes 11 hoạt động như thế nào? [đóng cửa]


297

ITunes 11 mới có chế độ xem rất đẹp cho danh sách bài hát của album, chọn màu cho phông chữ và nền trong chức năng của bìa album. Bất cứ ai cũng tìm ra làm thế nào các thuật toán hoạt động?

Ví dụ thứ ba


9
Công thức tương phản màu w3c có thể là một phần của câu trả lời. Các thử nghiệm theo vòng tròn của riêng tôi cho thấy rằng công thức này được MS Word sử dụng để quyết định phông chữ tự động màu của nó. Tìm kiếm "Độ sáng màu được xác định theo công thức sau" [công thức tương phản màu w3c] [1] [1]: w3.org/TR/AERT#color-contrast
bluedog

@bluedog, tôi nghĩ bạn nói đúng. Tôi đã thử rất nhiều bìa album của mình và luôn luôn phông chữ có đủ độ tương phản với nền để xem rõ ràng.
LuisEspinoza

1
Một điều khác cần lưu ý là dường như khác nhau giữa Mac OS và Windows: twitter.com/grimfrog/status/275187988374380546
Tom Irving

2
Tôi có thể tưởng tượng rằng có thể không chỉ số lượng màu, mà cả giá trị bão hòa của chúng cũng là một phần của phép tính: Các thí nghiệm của tôi đã đưa tôi đến kết luận, màu nổi bật thường được chọn làm màu nền mặc dù chúng xuất hiện ở một số khu vực hình ảnh. Đó là lý do tại sao tôi tin rằng việc nhìn vào biểu đồ của ảnh bìa và các đỉnh của nó có thể hữu ích, và dựa trên một số thông số được tinh chỉnh, màu sắc được chọn.
Raffael

2
Xem câu trả lời khác tại panic.com/blog/2012/12/itunes-11-and-colors
Mark Ransom

Câu trả lời:


423

ví dụ 1

Tôi đã tính gần đúng thuật toán màu iTunes 11 trong Mathicala với bìa album làm đầu vào:

Đầu ra 1

Làm thế nào tôi làm điều đó

Thông qua thử nghiệm và lỗi, tôi đã tìm ra một thuật toán hoạt động trên ~ 80% các album mà tôi đã thử nghiệm nó.

Sự khác biệt màu sắc

Phần lớn thuật toán liên quan đến việc tìm màu chủ đạo của hình ảnh. Tuy nhiên, một điều kiện tiên quyết để tìm màu chủ đạo là tính toán sự khác biệt có thể định lượng giữa hai màu. Một cách để tính toán sự khác biệt giữa hai màu là tính khoảng cách Euclide của chúng trong không gian màu RGB. Tuy nhiên, nhận thức màu sắc của con người không khớp với khoảng cách trong không gian màu RGB.

Do đó, tôi đã viết một hàm để chuyển đổi màu RGB (dưới dạng {1,1,1}) sang YUV , một không gian màu tốt hơn nhiều trong việc xấp xỉ nhận thức màu:

(EDIT: @cormullion@Drake đã chỉ ra rằng các không gian màu CIELAB và CIELUV tích hợp của Mathematica sẽ phù hợp ... có vẻ như tôi đã phát minh lại bánh xe một chút ở đây)

convertToYUV[rawRGB_] :=
    Module[{yuv},
        yuv = {{0.299, 0.587, 0.114}, {-0.14713, -0.28886, 0.436},
            {0.615, -0.51499, -0.10001}};
        yuv . rawRGB
    ]

Tiếp theo, tôi đã viết một hàm để tính khoảng cách màu với chuyển đổi ở trên:

ColorDistance[rawRGB1_, rawRGB2_] := 
    EuclideanDistance[convertToYUV @ rawRGB1, convertToYUV @ rawRGB2]

Màu sắc chủ đạo

Tôi nhanh chóng phát hiện ra rằng hàm DominantColorsMathicala tích hợp không cho phép đủ quyền kiểm soát chi tiết để xấp xỉ thuật toán mà iTunes sử dụng. Tôi đã viết chức năng của riêng mình thay vì ...

Một phương pháp đơn giản để tính toán màu chủ đạo trong một nhóm pixel là thu thập tất cả các pixel thành các thùng có màu tương tự và sau đó tìm thùng lớn nhất.

DominantColorSimple[pixelArray_] :=
    Module[{buckets},
        buckets = Gather[pixelArray, ColorDistance[#1,#2] < .1 &];
        buckets = Sort[buckets, Length[#1] > Length[#2] &];
        RGBColor @@ Mean @ First @ buckets
    ]

Lưu ý rằng .1dung sai cho các màu khác nhau phải được xem xét riêng biệt. Cũng lưu ý rằng mặc dù đầu vào là một mảng các pixel ở dạng bộ ba thô ( {{1,1,1},{0,0,0}}), tôi trả về một RGBColorphần tử Mathicala để xấp xỉ tốt hơn DominantColorshàm tích hợp.

Hàm thực tế của tôi DominantColorsNewthêm tùy chọn trở lại nmàu chủ đạo sau khi lọc ra một màu khác. Nó cũng cho thấy dung sai cho từng so sánh màu:

DominantColorsNew[pixelArray_, threshold_: .1, n_: 1, 
    numThreshold_: .2, filterColor_: 0, filterThreshold_: .5] :=
    Module[
        {buckets, color, previous, output},
        buckets = Gather[pixelArray, ColorDistance[#1, #2] < threshold &];
        If[filterColor =!= 0, 
        buckets = 
            Select[buckets, 
                ColorDistance[ Mean[#1], filterColor] > filterThreshold &]];
        buckets = Sort[buckets, Length[#1] > Length[#2] &];
        If[Length @ buckets == 0, Return[{}]];
        color = Mean @ First @ buckets;
        buckets = Drop[buckets, 1];
        output = List[RGBColor @@ color];
        previous = color;
        Do[
            If[Length @ buckets == 0, Return[output]];
            While[
                ColorDistance[(color = Mean @ First @ buckets), previous] < 
                    numThreshold, 
                If[Length @ buckets != 0, buckets = Drop[buckets, 1], 
                    Return[output]]
            ];
            output = Append[output, RGBColor @@ color];
            previous = color,
            {i, n - 1}
        ];
        output
    ]

Phần còn lại của thuật toán

Đầu tiên tôi thay đổi kích thước bìa album ( 36px, 36px) và giảm chi tiết bằng bộ lọc song phương

image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];

iTunes chọn màu nền bằng cách tìm màu chủ đạo dọc theo các cạnh của album. Tuy nhiên, nó bỏ qua các viền bìa album hẹp bằng cách cắt xén hình ảnh.

thumb = ImageCrop[thumb, 34];

Tiếp theo, tôi tìm thấy màu chủ đạo (với chức năng mới ở trên) dọc theo cạnh ngoài cùng của hình ảnh với dung sai mặc định là .1.

border = Flatten[
    Join[ImageData[thumb][[1 ;; 34 ;; 33]] , 
        Transpose @ ImageData[thumb][[All, 1 ;; 34 ;; 33]]], 1];
background = DominantColorsNew[border][[1]];

Cuối cùng, tôi trả lại toàn bộ 2 màu chủ đạo trong ảnh, nói với chức năng lọc cả màu nền.

highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2, 
    List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];

Các giá trị dung sai ở trên như sau: .1là sự khác biệt tối thiểu giữa các màu "riêng biệt"; .2là sự khác biệt tối thiểu giữa nhiều màu chủ đạo (Giá trị thấp hơn có thể trả về màu đen và xám đậm, trong khi giá trị cao hơn đảm bảo tính đa dạng hơn trong các màu chủ đạo); .5là sự khác biệt tối thiểu giữa các màu chủ đạo và nền (Giá trị cao hơn sẽ mang lại kết hợp màu tương phản cao hơn)

Voila!

Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]

Đầu ra cuối cùng

Ghi chú

Thuật toán có thể được áp dụng rất chung chung. Tôi đã điều chỉnh các cài đặt và giá trị dung sai ở trên đến điểm chúng hoạt động để tạo ra màu sắc thường chính xác cho ~ 80% bìa album tôi đã thử nghiệm. Một vài trường hợp cạnh xảy ra khi DominantColorsNewkhông tìm thấy hai màu để trả về các điểm nổi bật (nghĩa là khi bìa album là đơn sắc). Thuật toán của tôi không giải quyết được các trường hợp này, nhưng sẽ rất ít khi sao chép chức năng của iTunes: khi album mang lại ít hơn hai điểm nổi bật, tiêu đề trở thành màu trắng hoặc đen tùy thuộc vào độ tương phản tốt nhất với nền. Sau đó, các bài hát trở thành một màu nổi bật nếu có một, hoặc màu tiêu đề mờ dần vào nền một chút.

Thêm ví dụ

Thêm ví dụ


3
OK @Seth Thompson, có vẻ rất hứa hẹn. Tôi sẽ tự thử, tôi sẽ mất vài ngày, xin hãy kiên nhẫn.
LuisEspinoza

6
Giải pháp khá tuyệt vời. Bây giờ cần một cổng từ Mathicala đến Objective-C, đó là một cuộc đấu tranh khó khăn.
loretoparisi

1
+1 cho câu trả lời rất chi tiết này!
Marius Schulz

1
@cormullion LUV (và LAB) đều hướng đến sự đồng nhất về nhận thức. Tuy nhiên, tôi không tìm thấy bất kỳ tài liệu tham khảo rõ ràng nào về việc sử dụng khoảng cách euclide trong không gian màu. Tôi đoán là nếu không có gì khác, cả hai sẽ tốt hơn RGB.
Seth Thompson

6
Đây là những gì tôi muốn gọi là "Câu trả lời Chuck Norris"
MCKapur

44

Với câu trả lời của @ Seth-th trộm và nhận xét của @bluedog, tôi xây dựng một dự án Objective-C (Ca cao-Touch) nhỏ để tạo ra các lược đồ màu theo chức năng của một hình ảnh.

Bạn có thể kiểm tra dự án tại:

https://github.com/luisespinoza/LEColorPicker

Hiện tại, LEColorPicker đang làm:

  1. Hình ảnh được thu nhỏ đến 36x36 px (điều này làm giảm thời gian tính toán).
  2. Nó tạo ra một mảng pixel từ hình ảnh.
  3. Chuyển đổi mảng pixel thành không gian YUV.
  4. Thu thập màu sắc như mã của Seth Thompson làm điều đó.
  5. Các bộ màu được sắp xếp theo số lượng.
  6. Thuật toán chọn ba màu chủ đạo nhất.
  7. Sự thống trị nhất được gán cho nền.
  8. Các ưu thế thứ hai và thứ ba được kiểm tra bằng công thức tương phản màu w3c, để kiểm tra xem màu sắc có đủ độ tương phản với nền không.
  9. Nếu một trong các màu văn bản không vượt qua bài kiểm tra, thì được gán cho màu trắng hoặc đen, tùy thuộc vào thành phần Y.

Đó là bây giờ, tôi sẽ kiểm tra dự án ColorTunes ( https://github.com/Dannvix/ColorTunes ) và dự án Wade Cosgrove để biết các tính năng mới. Ngoài ra tôi có một số ý tưởng mới để cải thiện kết quả phối màu.

Ảnh chụp màn hình_Mona


2
+1 - Những thứ rất tuyệt, và một ví dụ tuyệt vời về cách phát triển thuật toán và phát triển ứng dụng có thể rất thú vị theo cách riêng của chúng
Yuval Karmi

1
+1 để kiểm tra độ tương phản.
brianmearn

Vâng tuyệt vời nhưng làm thế nào bạn làm tròn các giá trị băm cho mỗi màu? Tôi nghĩ rằng tôi có thể phá vỡ thuật toán này một cách dễ dàng, chỉ bằng cách thêm một biểu tượng "Rõ ràng" màu đen và trắng ở dưới cùng bên phải, bạn thực sự đang thêm trọng tâm cho màu đen và trắng. Dù sao, thuật toán này sẽ hoạt động tốt hơn đối với các hình ảnh dựa trên clip-art, nhưng nếu bạn có hình ảnh ở mức 36x36 thì các trường hợp thất bại đó sẽ trở nên hiếm hơn bởi tính năng khử răng cưa
Jack Franzen

Một từ: FANTASTIC!
Teddy

16

Wade Cosgrove of Panic đã viết một bài đăng trên blog rất hay mô tả việc anh ta thực hiện một thuật toán gần bằng thuật toán trong iTunes. Nó bao gồm một triển khai mẫu trong Objective-C.


15

Bạn cũng có thể kiểm tra ColorTunes , một triển khai HTML của chế độ xem album Itunes đang sử dụng thuật toán MMCQ (lượng tử hóa màu cắt trung bình).


vâng tôi đã kiểm tra rồi Đáng buồn là dường như hầu như không có tài liệu.
LuisEspinoza

Nhận xét quan trọng trong ColorTunes là tham chiếu đến (thuật toán lượng tử hóa cắt trung bình) [ leptonica.com/ con / mediancut.pdf] . Tôi vừa thực hiện điều này trên python trong khoảng 2 giờ chỉ cần hình thành mô tả trong bài báo và thích nó hơn là triển khai thuật toán của Seth ở trên. Tôi thích kết quả tốt hơn một chút, nhưng quan trọng nhất là nó nhanh hơn một chút (tất nhiên, tôi có thể đã thực hiện thuật toán của Seth không chính xác).
brianmearn

@ sh1ftst0rm Bạn có triển khai python trên github hoặc ở đâu đó không? chúc mừng
Anentropic

@Anentropic Xin lỗi, tôi không. Đó là một phần của một dự án tư nhân mà tôi đang thực hiện và tôi đã không trích xuất nó ra. Nếu tôi có cơ hội, tôi sẽ cố gắng đăng nó ở đâu đó, nhưng có lẽ nó sẽ không sớm thôi.
brianmearns



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.