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?
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?
Câu trả lời:
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:
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ó.
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 và @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]
Tôi nhanh chóng phát hiện ra rằng hàm DominantColors
Mathicala 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 .1
dung 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 RGBColor
phần tử Mathicala để xấp xỉ tốt hơn DominantColors
hàm tích hợp.
Hàm thực tế của tôi DominantColorsNew
thêm tùy chọn trở lại n
mà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
]
Đầ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: .1
là sự khác biệt tối thiểu giữa các màu "riêng biệt"; .2
là 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); .5
là 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[]}]
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 DominantColorsNew
khô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.
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:
Đó 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.
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.
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ới câu trả lời của @ Seth, tôi đã triển khai thuật toán để có được màu chủ đạo ở hai đường viền bên của hình ảnh bằng PHP và Imagick.
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
Nó đang được sử dụng để lấp đầy nền của ảnh bìa trong http://festea.com.br
Tôi vừa viết một thư viện JS thực hiện thuật toán gần giống với thuật toán được mô tả bởi @Seth . Nó được cung cấp miễn phí trên github.com/arcanis/colibrijs và trên NPM như colibrijs
.
Tôi đã hỏi cùng một câu hỏi trong một bối cảnh khác và được chỉ ra http://charlesleifer.com/blog/USE-python-and-k-means-to-find-the-dominant-colors-in-images/ cho một thuật toán học tập (k Means) thực sự làm điều tương tự bằng cách sử dụng các điểm bắt đầu ngẫu nhiên trong ảnh. Bằng cách đó, thuật toán tự tìm màu chủ đạo.