Skip to content

Commit f4caba5

Browse files
authored
Merge pull request #1703 from emmanuel-ferdman/main
Update array stacking for color standard processing
2 parents 88c5618 + 13d5ce7 commit f4caba5

1 file changed

Lines changed: 23 additions & 17 deletions

File tree

plantcv/plantcv/transform/color_correction.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def affine_color_correction(rgb_img, source_matrix, target_matrix):
3737
"""
3838
# matrices must have the same number of color references
3939
if source_matrix.shape != target_matrix.shape:
40-
fatal_error("Missmatch between the color matrices' shapes")
40+
fatal_error("Mismatch between the color matrices' shapes")
4141

4242
h, w, c = rgb_img.shape
4343

@@ -49,7 +49,7 @@ def affine_color_correction(rgb_img, source_matrix, target_matrix):
4949
# the affine transformation
5050
S = np.concatenate((source_matrix[:, 1:].copy(), np.ones((n, 1))), axis=1)
5151

52-
# make vectors of taget values for each color
52+
# make vectors of target values for each color
5353
T = target_matrix[:, 1:].copy()
5454
tr = T[:, 0]
5555
tg = T[:, 1]
@@ -62,7 +62,7 @@ def affine_color_correction(rgb_img, source_matrix, target_matrix):
6262
ab = np.matmul(np.linalg.pinv(S), tb)
6363

6464
img_rgb = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2RGB)
65-
# reshape image as a 2D array where the rows are pixels and the colums are color channels
65+
# reshape image as a 2D array where the rows are pixels and the columns are color channels
6666
# and augment the channels with a column of 1s for the affine transformation
6767
img_pix = np.concatenate((img_rgb.reshape(h*w, c).astype(np.float64)/255, np.ones((h*w, 1))), axis=1)
6868

@@ -85,7 +85,7 @@ def affine_color_correction(rgb_img, source_matrix, target_matrix):
8585
def std_color_matrix(pos=0):
8686
"""Create a standard color matrix.
8787
88-
Standard color values compatible with the x-rite ColorCheker Classic,
88+
Standard color values compatible with the x-rite ColorChecker Classic,
8989
ColorChecker Mini, and ColorChecker Passport targets.
9090
Source: https://en.wikipedia.org/wiki/ColorChecker
9191
@@ -106,7 +106,7 @@ def std_color_matrix(pos=0):
106106
:return color_matrix: numpy.ndarray
107107
"""
108108
# list of rgb values as indicated in the color card specs. They need to be
109-
# aranged depending on the orientation of the color card of reference in the
109+
# arranged depending on the orientation of the color card of reference in the
110110
# image to be corrected.
111111
values_list = np.array([[115, 82, 68], # dark skin
112112
[194, 150, 130], # light skin
@@ -140,7 +140,7 @@ def std_color_matrix(pos=0):
140140
N_chips = values_list.shape[0]
141141

142142
# array of indices from 1 to N chips in order to match the chip numbering
143-
# in the color card specs. Later when used for indexing, we substract the 1.
143+
# in the color card specs. Later when used for indexing, we subtract the 1.
144144
idx = np.arange(N_chips)+1
145145
# indices in the shape of the color card
146146
cc_indices = idx.reshape((4, 6), order='C')
@@ -235,8 +235,10 @@ def get_matrix_m(target_matrix, source_matrix):
235235
"""
236236
# if the number of chips in source_img match the number of chips in target_matrix
237237
if np.shape(target_matrix) == np.shape(source_matrix):
238-
_, t_r, t_g, t_b = np.split(target_matrix, 4, 1)
239-
_, s_r, s_g, s_b = np.split(source_matrix, 4, 1)
238+
t_mats = np.split(target_matrix, 4, 1)
239+
t_r, t_g, t_b = t_mats[1], t_mats[2], t_mats[3]
240+
s_mats = np.split(source_matrix, 4, 1)
241+
s_r, s_g, s_b = s_mats[1], s_mats[2], s_mats[3]
240242
else:
241243
combined_matrix = np.zeros((np.ma.size(source_matrix, 0), 7))
242244
row_count = 0
@@ -251,7 +253,8 @@ def get_matrix_m(target_matrix, source_matrix):
251253
combined_matrix[row_count][5] = source_matrix[i][2]
252254
combined_matrix[row_count][6] = source_matrix[i][3]
253255
row_count += 1
254-
_, t_r, t_g, t_b, s_r, s_g, s_b = np.split(combined_matrix, 7, 1)
256+
rgb_mats = np.split(combined_matrix, 7, 1)
257+
t_r, t_g, t_b, s_r, s_g, s_b = rgb_mats[1], rgb_mats[2], rgb_mats[3], rgb_mats[4], rgb_mats[5], rgb_mats[6]
255258
t_r2 = np.square(t_r)
256259
t_r3 = np.power(t_r, 3)
257260
t_g2 = np.square(t_g)
@@ -305,8 +308,10 @@ def calc_transformation_matrix(matrix_m, matrix_b):
305308
if np.shape(matrix_m)[0] != np.shape(matrix_b)[1] or np.shape(matrix_m)[1] != np.shape(matrix_b)[0]:
306309
fatal_error("Cannot multiply matrices.")
307310

308-
t_r, t_r2, t_r3, t_g, t_g2, t_g3, t_b, t_b2, t_b3 = np.split(matrix_b, 9, 1)
309-
311+
t_mats = np.split(matrix_b, 9, 1)
312+
t_r, t_r2, t_r3 = t_mats[0], t_mats[1], t_mats[2]
313+
t_g, t_g2, t_g3 = t_mats[3], t_mats[4], t_mats[5]
314+
t_b, t_b2, t_b3 = t_mats[6], t_mats[7], t_mats[8]
310315
# multiply each 22x1 matrix from target color space by matrix_m
311316
red = np.matmul(matrix_m, t_r)
312317
green = np.matmul(matrix_m, t_g)
@@ -335,7 +340,7 @@ def apply_transformation_matrix(source_img, target_img, transformation_matrix):
335340
Inputs:
336341
source_img = an RGB image to be corrected to the target color space
337342
target_img = an RGB image with the target color space
338-
transformation_matrix = a 9x9 matrix of tranformation coefficients
343+
transformation_matrix = a 9x9 matrix of transformation coefficients
339344
340345
Outputs:
341346
corrected_img = an RGB image in correct color space
@@ -353,7 +358,8 @@ def apply_transformation_matrix(source_img, target_img, transformation_matrix):
353358
fatal_error("Source_img is not an RGB image.")
354359

355360
# split transformation_matrix
356-
red, green, blue, _, _, _, _, _, _ = np.split(transformation_matrix, 9, 1)
361+
channels = np.split(transformation_matrix, 9, 1)
362+
red, green, blue = channels[0], channels[1], channels[2]
357363

358364
source_dtype = source_img.dtype
359365
# normalization value as max number if the type is unsigned int
@@ -395,7 +401,7 @@ def apply_transformation_matrix(source_img, target_img, transformation_matrix):
395401
out_img = ((255.0/max_val)*out_img).astype(np.uint8)
396402
_debug(visual=out_img, filename=os.path.join(params.debug_outdir, str(params.device) + '_corrected.png'))
397403

398-
# return corrected_img
404+
# return the corrected image
399405
return corrected_img
400406

401407

@@ -539,7 +545,7 @@ def create_color_card_mask(rgb_img, radius, start_coord, spacing, nrows, ncols,
539545
for chip in exclude:
540546
del chips[chip]
541547
# Create mask
542-
mask = np.zeros(shape=np.shape(rgb_img)[:2], dtype=np.uint8())
548+
mask = np.zeros(shape=np.shape(rgb_img)[:2], dtype=np.uint8)
543549
# Mask label index
544550
i = 1
545551
# Draw labeled chip boxes on the mask
@@ -596,13 +602,13 @@ def quick_color_check(target_matrix, source_matrix, num_chips):
596602

597603
# Make a column of chip numbers
598604
chip = np.arange(0, num_chips).reshape((num_chips, 1))
599-
chips = np.row_stack((chip, chip, chip))
605+
chips = np.vstack((chip, chip, chip))
600606

601607
# Combine info
602608
color_data_r = np.column_stack((sr, tr, red))
603609
color_data_g = np.column_stack((sg, tg, green))
604610
color_data_b = np.column_stack((sb, tb, blue))
605-
all_color_data = np.row_stack((color_data_b, color_data_g, color_data_r))
611+
all_color_data = np.vstack((color_data_b, color_data_g, color_data_r))
606612

607613
# Create a dataframe with headers
608614
dataset = pd.DataFrame({'source': all_color_data[:, 0], 'target': all_color_data[:, 1],

0 commit comments

Comments
 (0)