At the moment, I think the program just crashes if there's no match in the DB. It should be impossible for the initial lookup to fail because the DB has a row for every possible CMYK color but in the second lookup has crashed the program because for example it'll narrow the options down to 10 colors and I'll ask it to select 11 colors. I have actually done something similar before for testing purposes and the program just crashed.
Also, everything is on my computer at work but I can share everything when I go back on Monday (in 31 hours), the code, the DB, some sample images it made.
Because I work in a textile mill we make colors by printing images on paper with a CMYK process and then we use heat to sublimate the ink off of the paper onto the textile. In this process there are so many variables affecting the color of the ink that it's basically a black box where CMYK numbers go in and very often the wrong color comes out. The only way to match colors is to pick a lot of them, and see which one is the most accurate after transfer and use that one. The process of picking those colors is what I'm working on.
A long time ago someone told me about how to calibrate a printer system . IIRC yuo get an image in the computer and a printer version with a bunch of colors. Then you print the image and scan the original and the new version. Then the software compare both, and make some corrections. Now you repeat the process a few times, until the image you print is equal to the image you got initially. I'm not sure if the systems assumes to many details that are specific for the printer.
---
IIUC one of the problems is that the CMYK in the computer is very different from the CMYK you get in the fabric. Perhaps you can print in paper using normal ink a version of https://www.google.com/search?q=color+tv+calibration&tbm=isc... and then print the same image in the fabric using sublimation. Then scan both and compare them. Perhaps make a custom image with a lot of small squares to cover all the CMYK space, like
{00, 40, 80, C0, FF} x {00, 40, 80, C0, FF} x {00, 40, 80, C0, FF} x {00, 40, 80, C0, FF}
because I remember that FFFFFF00 is a horrible dark brown color and 000000FF is a nice black color, but TV doesn't care about that detail.
Perhaps print multiple images, to sample more points in the the CYMK space. As many as possible without making everyone hate you.
So now you have two functions, F and G:
F(CMYK_computer) = CMYK_paper
G(CMYK_computer) = CMYK_fabic
and you want a third function H that convert the initial CMYK color into a fake CMYK color that printed in the fabric is equal to the result of the initial one in paper.
H(CMYK_computer) = CMYK_fake
G(CMYK_fake) = CMYK_paper
G(H(CMYK_computer) = F(CMYK_computer)
so H is defined as
H(CMYK_computer)=invG(F(CMYK_computer))
Calculating the inverse of G may be difficult, but my guess is that interpolation or machine learning should solve the problem. Also, the inverse of G may not be defined in some cases, so you should add some clipping to avoid raising an error.
It looks like an interesting problem (not easy, but not impossible).
The source color is in the top left corner and below it are colors darker than it ordered by lightness descending from top left to bottom right. The hue of all the colors is supposed to be similar but there is so much variance in the hue that really only 20% of these colors are usable.
This image would be printed out and if one of the colors is more accurate after printing, then the source color in the original art would be replaced with that other more accurate color.
I think you have too much samples in your databas. I think it's better to sample a much smaller range like 4x4x4x4 in the CYMK space, and interpolate the other values. (Perhaps 4x4x4x4 is too low, and you should use 16x16x16x16, or sample using an uneven grid because the easy grid will probably be full of dark brown versions.)
If some day you have some free time, it would be nice to read a blog post explaining the problem and the solution. If you add some photos it could get some traction here (or not, nobody is sure what gets traction).
Comments
At the moment, I think the program just crashes if there's no match in the DB. It should be impossible for the initial lookup to fail because the DB has a row for every possible CMYK color but in the second lookup has crashed the program because for example it'll narrow the options down to 10 colors and I'll ask it to select 11 colors. I have actually done something similar before for testing purposes and the program just crashed.
Also, everything is on my computer at work but I can share everything when I go back on Monday (in 31 hours), the code, the DB, some sample images it made.
Because I work in a textile mill we make colors by printing images on paper with a CMYK process and then we use heat to sublimate the ink off of the paper onto the textile. In this process there are so many variables affecting the color of the ink that it's basically a black box where CMYK numbers go in and very often the wrong color comes out. The only way to match colors is to pick a lot of them, and see which one is the most accurate after transfer and use that one. The process of picking those colors is what I'm working on.
I'm still not sure what you want to do. Is it "posterize" or "dither" or something else? Why do you want to pick exactly 10 colors?
Posterize: https://docs.gimp.org/2.10/en/gimp-filter-posterize.html https://www.google.com/search?q=Posterize&tbm=isch Last year my wife wanted to posterize some photos to make street graffiti. She tried like 5 online and offline versions and got bad results. I tried a few more and also got bad results. So she pick the best one and made a lot of manual corrections. It looks like a hard problem.
Dither: https://docs.gimp.org/2.10/en/gimp-filter-dither.html https://www.google.com/search?q=Dither&tbm=isch I used this a long time ago and got good results, but it was a long time ago so I may be misremembering.
---
A long time ago someone told me about how to calibrate a printer system . IIRC yuo get an image in the computer and a printer version with a bunch of colors. Then you print the image and scan the original and the new version. Then the software compare both, and make some corrections. Now you repeat the process a few times, until the image you print is equal to the image you got initially. I'm not sure if the systems assumes to many details that are specific for the printer.
---
IIUC one of the problems is that the CMYK in the computer is very different from the CMYK you get in the fabric. Perhaps you can print in paper using normal ink a version of https://www.google.com/search?q=color+tv+calibration&tbm=isc... and then print the same image in the fabric using sublimation. Then scan both and compare them. Perhaps make a custom image with a lot of small squares to cover all the CMYK space, like
{00, 40, 80, C0, FF} x {00, 40, 80, C0, FF} x {00, 40, 80, C0, FF} x {00, 40, 80, C0, FF}
because I remember that FFFFFF00 is a horrible dark brown color and 000000FF is a nice black color, but TV doesn't care about that detail.
Perhaps print multiple images, to sample more points in the the CYMK space. As many as possible without making everyone hate you.
So now you have two functions, F and G:
F(CMYK_computer) = CMYK_paper
G(CMYK_computer) = CMYK_fabic
and you want a third function H that convert the initial CMYK color into a fake CMYK color that printed in the fabric is equal to the result of the initial one in paper.
H(CMYK_computer) = CMYK_fake
G(CMYK_fake) = CMYK_paper
G(H(CMYK_computer) = F(CMYK_computer)
so H is defined as
H(CMYK_computer)=invG(F(CMYK_computer))
Calculating the inverse of G may be difficult, but my guess is that interpolation or machine learning should solve the problem. Also, the inverse of G may not be defined in some cases, so you should add some clipping to avoid raising an error.
It looks like an interesting problem (not easy, but not impossible).
The database is 8 gigabytes so it will take a minute to upload, but I put one of the output images on imgur:
https://imgur.com/a/oMtVDYO
The source color is in the top left corner and below it are colors darker than it ordered by lightness descending from top left to bottom right. The hue of all the colors is supposed to be similar but there is so much variance in the hue that really only 20% of these colors are usable.
This image would be printed out and if one of the colors is more accurate after printing, then the source color in the original art would be replaced with that other more accurate color.
I think you have too much samples in your databas. I think it's better to sample a much smaller range like 4x4x4x4 in the CYMK space, and interpolate the other values. (Perhaps 4x4x4x4 is too low, and you should use 16x16x16x16, or sample using an uneven grid because the easy grid will probably be full of dark brown versions.)
Anyway, it looks like someone else gave a better hint and you were able to solve your problem :) https://news.ycombinator.com/item?id=37643761
---
If some day you have some free time, it would be nice to read a blog post explaining the problem and the solution. If you add some photos it could get some traction here (or not, nobody is sure what gets traction).