comparison layer/ColourDatabase.cpp @ 1578:57a4ee52ad69 background-mode

Make nearby-colour matching a bit more sophisticated, with slightly better algorithm (we think?) and ability to insist on dark/light background
author Chris Cannam
date Fri, 24 Jan 2020 12:40:07 +0000
parents ad86aa712d11
children
comparison
equal deleted inserted replaced
1577:2c974337f306 1578:57a4ee52ad69
86 86
87 return -1; 87 return -1;
88 } 88 }
89 89
90 int 90 int
91 ColourDatabase::getNearbyColourIndex(QColor col) const 91 ColourDatabase::getNearbyColourIndex(QColor col, WithBackgroundMode mode) const
92 { 92 {
93 int index = 0; 93 int index = -1;
94 int closestIndex = -1; 94 int closestIndex = -1;
95 int closestDistance = 0; 95 double closestDistance = 0;
96 96
97 for (auto &c: m_colours) { 97 for (auto &c: m_colours) {
98 int distance = 98
99 std::abs(col.red() - c.colour.red()) + 99 ++index;
100 std::abs(col.green() - c.colour.green()) + 100
101 std::abs(col.blue() - c.colour.blue()); 101 if (mode == WithDarkBackground && !c.darkbg) {
102 #ifdef DEBUG_COLOUR_DATABASE
103 SVDEBUG << "getNearbyColourIndex: dark background requested, skipping " << c.colour.name() << endl;
104 #endif
105 continue;
106 }
107 if (mode == WithLightBackground && c.darkbg) {
108 #ifdef DEBUG_COLOUR_DATABASE
109 SVDEBUG << "getNearbyColourIndex: light background requested, skipping " << c.colour.name() << endl;
110 #endif
111 continue;
112 }
113
114 // This distance formula is "one of the better low-cost
115 // approximations" according to
116 // https://en.wikipedia.org/w/index.php?title=Color_difference&oldid=936888327
117
118 double r1 = col.red(), r2 = c.colour.red();
119 double g1 = col.green(), g2 = c.colour.green();
120 double b1 = col.blue(), b2 = c.colour.blue();
121
122 double rav = (r1 + r2) / 2.0;
123 double rterm = (2.0 + rav / 256.0) * (r1 - r2) * (r1 - r2);
124 double gterm = 4.0 * (g1 - g2) * (g1 - g2);
125 double bterm = (2.0 + (255 - rav) / 256.0) * (b1 - b2) * (b1 - b2);
126
127 double distance = sqrt(rterm + gterm + bterm);
128
102 #ifdef DEBUG_COLOUR_DATABASE 129 #ifdef DEBUG_COLOUR_DATABASE
103 SVDEBUG << "getNearbyColourIndex: comparing " << c.colour.name() 130 SVDEBUG << "getNearbyColourIndex: comparing " << c.colour.name()
104 << " to " << col.name() << ": distance = " << distance << endl; 131 << " to " << col.name() << ": distance = " << distance << endl;
105 #endif 132 #endif
106 if (closestIndex < 0 || distance < closestDistance) { 133 if (closestIndex < 0 || distance < closestDistance) {
108 closestDistance = distance; 135 closestDistance = distance;
109 #ifdef DEBUG_COLOUR_DATABASE 136 #ifdef DEBUG_COLOUR_DATABASE
110 SVDEBUG << "(this is the best so far)" << endl; 137 SVDEBUG << "(this is the best so far)" << endl;
111 #endif 138 #endif
112 } 139 }
113 ++index;
114 } 140 }
115 141
116 #ifdef DEBUG_COLOUR_DATABASE 142 #ifdef DEBUG_COLOUR_DATABASE
117 SVDEBUG << "returning " << closestIndex << endl; 143 SVDEBUG << "returning " << closestIndex << endl;
118 #endif 144 #endif