From ba2dea194bc4b6d2ffd077cc2b2d0d51d7ca2ba4 Mon Sep 17 00:00:00 2001 From: lxowalle Date: Tue, 16 Apr 2024 10:47:47 +0800 Subject: [PATCH] * implement lab2rgb & rgb2lab --- examples/maixpy_v1/image/invert_format.py | 14 ++ maix/v1/image.py | 166 +++++++++++++++++++++- 2 files changed, 176 insertions(+), 4 deletions(-) diff --git a/examples/maixpy_v1/image/invert_format.py b/examples/maixpy_v1/image/invert_format.py index 3dc51695..3980b70c 100644 --- a/examples/maixpy_v1/image/invert_format.py +++ b/examples/maixpy_v1/image/invert_format.py @@ -18,5 +18,19 @@ lcd.display(img) time.sleep(1) +rgb=(100,200,30) +lab=image.rgb_to_lab(rgb) +print('rgb to lab, res:', lab) + +rgb=image.lab_to_rgb(lab) +print('lab to rgb, res:', rgb) + +rgb=(10,20,30) +gray=image.rgb_to_grayscale(rgb) +print('rgb to gray, res:', gray) + +rgb=image.grayscale_to_rgb(gray) +print('gray to rgb, res:', rgb) + while True: time.sleep(1) diff --git a/maix/v1/image.py b/maix/v1/image.py index beadb377..201d4cf6 100644 --- a/maix/v1/image.py +++ b/maix/v1/image.py @@ -1,4 +1,5 @@ from maix import image +import math SEARCH_EX = 0 SEARCH_DS = 1 @@ -718,17 +719,174 @@ def find_edges(self, edge_type, threshold): return img_v1 +def RGB2XYZ(r, g, b): + x = 0.412453 * r + 0.357580 * g + 0.180423 * b + y = 0.212671 * r + 0.715160 * g + 0.072169 * b + z = 0.019334 * r + 0.119193 * g + 0.950227 * b + return x, y, z + +def XYZ2Lab(x, y, z): + Xn = 1.0 + Yn = 1.0 + Zn = 1.0 + param_13 = 1.0 / 3.0 + param_16116 = 16.0 / 116.0 + + x /= 255 * Xn + y /= 255 * Yn + z /= 255 * Zn + if y > 0.008856: + fy = pow(y, param_13) + l = 116.0 * fy - 16.0 + else: + fy = 7.787 * y + param_16116 + l = 903.3 * fy + + if l < 0: + l = 0.0 + + if x>0.008856: + fx = pow(x,param_13) + else: + fx = 7.787 * x + param_16116 + + if z>0.008856: + fz = pow(z,param_13) + else: + fz = 7.787 * z + param_16116 + + a = 500.0*(fx-fy) + b = 200.0*(fy-fz) + + return (round(l,2), round(a,2), round(b,2)) + +__xyz_table = [ + 0.000000, 0.030353, 0.060705, 0.091058, 0.121411, 0.151763, 0.182116, 0.212469, + 0.242822, 0.273174, 0.303527, 0.334654, 0.367651, 0.402472, 0.439144, 0.477695, + 0.518152, 0.560539, 0.604883, 0.651209, 0.699541, 0.749903, 0.802319, 0.856813, + 0.913406, 0.972122, 1.032982, 1.096009, 1.161225, 1.228649, 1.298303, 1.370208, + 1.444384, 1.520851, 1.599629, 1.680738, 1.764195, 1.850022, 1.938236, 2.028856, + 2.121901, 2.217388, 2.315337, 2.415763, 2.518686, 2.624122, 2.732089, 2.842604, + 2.955683, 3.071344, 3.189603, 3.310477, 3.433981, 3.560131, 3.688945, 3.820437, + 3.954624, 4.091520, 4.231141, 4.373503, 4.518620, 4.666509, 4.817182, 4.970657, + 5.126946, 5.286065, 5.448028, 5.612849, 5.780543, 5.951124, 6.124605, 6.301002, + 6.480327, 6.662594, 6.847817, 7.036010, 7.227185, 7.421357, 7.618538, 7.818742, + 8.021982, 8.228271, 8.437621, 8.650046, 8.865559, 9.084171, 9.305896, 9.530747, + 9.758735, 9.989873, 10.224173, 10.461648, 10.702310, 10.946171, 11.193243, 11.443537, + 11.697067, 11.953843, 12.213877, 12.477182, 12.743768, 13.013648, 13.286832, 13.563333, + 13.843162, 14.126329, 14.412847, 14.702727, 14.995979, 15.292615, 15.592646, 15.896084, + 16.202938, 16.513219, 16.826940, 17.144110, 17.464740, 17.788842, 18.116424, 18.447499, + 18.782077, 19.120168, 19.461783, 19.806932, 20.155625, 20.507874, 20.863687, 21.223076, + 21.586050, 21.952620, 22.322796, 22.696587, 23.074005, 23.455058, 23.839757, 24.228112, + 24.620133, 25.015828, 25.415209, 25.818285, 26.225066, 26.635560, 27.049779, 27.467731, + 27.889426, 28.314874, 28.744084, 29.177065, 29.613827, 30.054379, 30.498731, 30.946892, + 31.398871, 31.854678, 32.314321, 32.777810, 33.245154, 33.716362, 34.191442, 34.670406, + 35.153260, 35.640014, 36.130678, 36.625260, 37.123768, 37.626212, 38.132601, 38.642943, + 39.157248, 39.675523, 40.197778, 40.724021, 41.254261, 41.788507, 42.326767, 42.869050, + 43.415364, 43.965717, 44.520119, 45.078578, 45.641102, 46.207700, 46.778380, 47.353150, + 47.932018, 48.514994, 49.102085, 49.693300, 50.288646, 50.888132, 51.491767, 52.099557, + 52.711513, 53.327640, 53.947949, 54.572446, 55.201140, 55.834039, 56.471151, 57.112483, + 57.758044, 58.407842, 59.061884, 59.720179, 60.382734, 61.049557, 61.720656, 62.396039, + 63.075714, 63.759687, 64.447968, 65.140564, 65.837482, 66.538730, 67.244316, 67.954247, + 68.668531, 69.387176, 70.110189, 70.837578, 71.569350, 72.305513, 73.046074, 73.791041, + 74.540421, 75.294222, 76.052450, 76.815115, 77.582222, 78.353779, 79.129794, 79.910274, + 80.695226, 81.484657, 82.278575, 83.076988, 83.879901, 84.687323, 85.499261, 86.315721, + 87.136712, 87.962240, 88.792312, 89.626935, 90.466117, 91.309865, 92.158186, 93.011086, + 93.868573, 94.730654, 95.597335, 96.468625, 97.344529, 98.225055, 99.110210, 100.000000 +] + def rgb_to_lab(rgb_tuple): - raise ValueError('This operation is not supported') + r = int(rgb_tuple[0]) + g = int(rgb_tuple[1]) + b = int(rgb_tuple[2]) + + r_lin = __xyz_table[r] + g_lin = __xyz_table[g] + b_lin = __xyz_table[b] + + x = ((r_lin * 0.4124) + (g_lin * 0.3576) + (b_lin * 0.1805)) * (1.0 / 95.047) + y = ((r_lin * 0.2126) + (g_lin * 0.7152) + (b_lin * 0.0722)) * (1.0 / 100.000) + z = ((r_lin * 0.0193) + (g_lin * 0.1192) + (b_lin * 0.9505)) * (1.0 / 108.883) + + if x > 0.008856: + x = x ** (1 / 3) + else: + x = (x * 7.787037) + 0.137931 + + if y > 0.008856: + y = y ** (1 / 3) + else: + y = (y * 7.787037) + 0.137931 + + if z > 0.008856: + z = z ** (1 / 3) + else: + z = (z * 7.787037) + 0.137931 + + l = max(min(math.floor(116 * y) - 16, 100), 0) + a = max(min(math.floor(500 * (x-y)), 127), -128) + b = max(min(math.floor(200 * (y-z)), 127), -128) + + return (l,a,b) def lab_to_rgb(lab_tuple): - raise ValueError('This operation is not supported') + l = int(lab_tuple[0]) + a = int(lab_tuple[1]) + b = int(lab_tuple[2]) + + x = ((l + 16) * 0.008621) + (a * 0.002) + y = ((l + 16) * 0.008621) + z = ((l + 16) * 0.008621) - (b * 0.005) + + if x > 0.206897: + x = x * x * x * 95.047 + else: + x = (((0.128419 * x) - 0.017713)) * 95.047 + + if y > 0.206897: + y = y * y * y * 100.000 + else: + y = ((0.128419 * y) - 0.017713) * 100.000 + + if z > 0.206897: + z = z * z * z * 108.883 + else: + z = ((0.128419 * z) - 0.017713) * 108.883 + + r_lin = ((x * +3.2406) + (y * -1.5372) + (z * -0.4986)) / 100.0 + g_lin = ((x * -0.9689) + (y * +1.8758) + (z * +0.0415)) / 100.0 + b_lin = ((x * +0.0557) + (y * -0.2040) + (z * +1.0570)) / 100.0 + + if r_lin > 0.0031308: + r_lin = 1.055 * (r_lin ** 0.416666) - 0.055 + else: + r_lin = r_lin * 12.92 + + if g_lin > 0.0031308: + g_lin = 1.055 * (g_lin ** 0.416666) - 0.055 + else: + g_lin = g_lin * 12.92 + + if b_lin > 0.0031308: + b_lin = 1.055 * (b_lin ** 0.416666) - 0.055 + else: + r_lin = r_lin * 12.92 + + r = max(min(math.floor(r_lin * 255), 255), 0) + g = max(min(math.floor(g_lin * 255), 255), 0) + b = max(min(math.floor(b_lin * 255), 255), 0) + + return (r,g,b) def rgb_to_grayscale(rgb_tuple): - raise ValueError('This operation is not supported') + r = rgb_tuple[0] + g = rgb_tuple[1] + b = rgb_tuple[2] + y = ((((r) * 38) + ((g) * 75) + ((b) * 15)) >> 7) + return y def grayscale_to_rgb(g_value): - raise ValueError('This operation is not supported') + return (g_value, g_value, g_value) def load_decriptor(path): raise ValueError('This operation is not supported')