Skip to content

Commit c1d934c

Browse files
committed
pbio/color: Introduce cost function type.
Sets the stage for the next commits. This does not change any color detection code yet.
1 parent cf7b771 commit c1d934c

4 files changed

Lines changed: 26 additions & 21 deletions

File tree

lib/pbio/include/pbio/color.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ void pbio_color_to_hsv(pbio_color_t color, pbio_color_hsv_t *hsv);
118118
void pbio_color_to_rgb(pbio_color_t color, pbio_color_rgb_t *rgb);
119119
void pbio_color_hsv_compress(const pbio_color_hsv_t *hsv, pbio_color_compressed_hsv_t *compressed);
120120
void pbio_color_hsv_expand(const pbio_color_compressed_hsv_t *compressed, pbio_color_hsv_t *hsv);
121-
int32_t pbio_color_get_bicone_squared_distance(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b);
121+
122+
typedef int32_t (*pbio_color_distance_func_t)(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b);
123+
124+
int32_t pbio_color_get_distance_bicone_squared(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b);
122125

123126
#endif // _PBIO_COLOR_H_
124127

lib/pbio/src/color/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* @param [in] hsv_b The second HSV color.
1414
* @returns Squared distance (0 to 400000000).
1515
*/
16-
int32_t pbio_color_get_bicone_squared_distance(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b) {
16+
int32_t pbio_color_get_distance_bicone_squared(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b) {
1717

1818
// Chroma (= radial coordinate in bicone) of a and b (0-10000).
1919
int32_t radius_a = pbio_color_hsv_get_v(hsv_a) * hsv_a->s;

lib/pbio/test/src/test_color.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ static void test_color_hsv_cost(void *env) {
366366
color_a.h = 0;
367367
color_a.s = 100;
368368
color_a.v = 100;
369-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_a), ==, 0);
369+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_a), ==, 0);
370370

371371
// blacks with different saturations/hues should be the same
372372
color_a.h = 230;
@@ -376,7 +376,7 @@ static void test_color_hsv_cost(void *env) {
376376
color_b.h = 23;
377377
color_b.s = 99;
378378
color_b.v = 0;
379-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), ==, 0);
379+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), ==, 0);
380380

381381
// colors with different hues should be different when value>0 and saturation>0
382382
color_a.h = 230;
@@ -386,7 +386,7 @@ static void test_color_hsv_cost(void *env) {
386386
color_b.h = 23;
387387
color_b.s = 99;
388388
color_b.v = 100;
389-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, 0);
389+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, 0);
390390

391391
// grays with different hues should be the same
392392
color_a.h = 230;
@@ -396,7 +396,7 @@ static void test_color_hsv_cost(void *env) {
396396
color_b.h = 23;
397397
color_b.s = 0;
398398
color_b.v = 50;
399-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), ==, 0);
399+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), ==, 0);
400400

401401
// distance should be greater when saturation is greater
402402
color_a.h = 30;
@@ -407,7 +407,7 @@ static void test_color_hsv_cost(void *env) {
407407
color_b.s = 20;
408408
color_b.v = 70;
409409

410-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
410+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
411411

412412
color_a.h = 30;
413413
color_a.s = 40;
@@ -417,7 +417,7 @@ static void test_color_hsv_cost(void *env) {
417417
color_b.s = 40;
418418
color_b.v = 70;
419419

420-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, dist);
420+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, dist);
421421

422422
// resolve colors that are close
423423
color_a.h = 30;
@@ -428,7 +428,7 @@ static void test_color_hsv_cost(void *env) {
428428
color_b.s = 20;
429429
color_b.v = 70;
430430

431-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, 0);
431+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, 0);
432432

433433
color_a.h = 30;
434434
color_a.s = 20;
@@ -438,7 +438,7 @@ static void test_color_hsv_cost(void *env) {
438438
color_b.s = 25;
439439
color_b.v = 70;
440440

441-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, 0);
441+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, 0);
442442

443443
color_a.h = 30;
444444
color_a.s = 20;
@@ -448,7 +448,7 @@ static void test_color_hsv_cost(void *env) {
448448
color_b.s = 20;
449449
color_b.v = 75;
450450

451-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, 0);
451+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, 0);
452452

453453
// hues 360 and 0 should be the same
454454
color_a.h = 360;
@@ -458,7 +458,7 @@ static void test_color_hsv_cost(void *env) {
458458
color_b.h = 0;
459459
color_b.s = 100;
460460
color_b.v = 100;
461-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), ==, 0);
461+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), ==, 0);
462462

463463
// distance between hues 359 and 1 should be smaller than hues 1 and 5
464464
color_a.h = 359;
@@ -468,7 +468,7 @@ static void test_color_hsv_cost(void *env) {
468468
color_b.h = 1;
469469
color_b.s = 100;
470470
color_b.v = 100;
471-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
471+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
472472

473473
color_a.h = 1;
474474
color_a.s = 100;
@@ -478,7 +478,7 @@ static void test_color_hsv_cost(void *env) {
478478
color_b.s = 100;
479479
color_b.v = 100;
480480

481-
tt_want_int_op(pbio_color_get_bicone_squared_distance(&color_a, &color_b), >, dist);
481+
tt_want_int_op(pbio_color_get_distance_bicone_squared(&color_a, &color_b), >, dist);
482482

483483
// check distance is monotonous along several color paths. This should catch potential int overflows
484484
int prev_dist = 0;
@@ -495,7 +495,7 @@ static void test_color_hsv_cost(void *env) {
495495

496496
while (color_a.s < 100) {
497497
color_a.s += 5;
498-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
498+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
499499

500500
if (dist <= prev_dist) {
501501
monotone = false;
@@ -520,7 +520,7 @@ static void test_color_hsv_cost(void *env) {
520520

521521
while (color_a.v < 100) {
522522
color_a.v += 5;
523-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
523+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
524524

525525
if (dist <= prev_dist) {
526526
monotone = false;
@@ -545,7 +545,7 @@ static void test_color_hsv_cost(void *env) {
545545

546546
while (color_a.v < 100) {
547547
color_a.v += 5;
548-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
548+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
549549

550550
if (dist <= prev_dist) {
551551
monotone = false;
@@ -573,7 +573,7 @@ static void test_color_hsv_cost(void *env) {
573573
color_a.h = i < 0 ? 180 : 0;
574574
color_a.v = 10000 / (200 - color_a.s); // constant lightness
575575

576-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
576+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
577577

578578
if (dist <= prev_dist) {
579579
monotone = false;
@@ -592,7 +592,7 @@ static void test_color_hsv_cost(void *env) {
592592
color_b.s = 100;
593593
color_b.v = 100;
594594

595-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
595+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
596596
tt_want_int_op(dist, >, 390000000);
597597
tt_want_int_op(dist, <, 410000000);
598598

@@ -604,7 +604,7 @@ static void test_color_hsv_cost(void *env) {
604604
color_b.s = 0;
605605
color_b.v = 100;
606606

607-
dist = pbio_color_get_bicone_squared_distance(&color_a, &color_b);
607+
dist = pbio_color_get_distance_bicone_squared(&color_a, &color_b);
608608
tt_want_int_op(dist, >, 390000000);
609609
tt_want_int_op(dist, <, 410000000);
610610
}

pybricks/util_pb/pb_color_map.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ mp_obj_t pb_color_map_get_color(mp_obj_t *color_map, pbio_color_hsv_t *hsv) {
7575
int32_t cost_now = INT32_MAX;
7676
int32_t cost_min = INT32_MAX;
7777

78+
pbio_color_distance_func_t distance_func = pbio_color_get_distance_bicone_squared;
79+
7880
// Compute cost for each candidate
7981
for (size_t i = 0; i < n; i++) {
8082

8183
// Evaluate the cost function
82-
cost_now = pbio_color_get_bicone_squared_distance(hsv, pb_type_Color_get_hsv(colors[i]));
84+
cost_now = distance_func(hsv, pb_type_Color_get_hsv(colors[i]));
8385

8486
// If cost is less than before, update the minimum and the match
8587
if (cost_now < cost_min) {

0 commit comments

Comments
 (0)