Colour pattern reading using only Lab or HSV.

42 views (last 30 days)
Stephen Otieno
Stephen Otieno on 14 Apr 2020
Commented: DGM on 5 Mar 2023
I have an image with squres with different colours: red, green, blue, yellow and white (see attached image). Im wondering if it possible to select a group of pixels on each individual square and for the selected pixels to represent the colour and producing an array of 4x4 matrix.

Answers (2)

Image Analyst
Image Analyst on 15 Apr 2020
Edited: Image Analyst on 16 Apr 2020
I would convert to HSV color space and then threshold the S channel to get the squares. Then use the mask and regionprops() to get the meanIntensity of each square. Here's a start/hint:
hsvImage = rgb2hsv(rgbImage);
mask = hsvImage(:, :, 2) > 0.25; % Only consider really vivid pixels, not gray ones.
mask = bwareaopen(mask, 1000); % Remove noise.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Get red means
props = regionprops(mask, redChannel, 'MeanIntensity');
allMeansR = [props.MeanIntensity];
% Get green means
props = regionprops(mask, greenChannel, 'MeanIntensity');
allMeansG = [props.MeanIntensity];
% Get red means
props = regionprops(mask, blueChannel, 'MeanIntensity');
allMeansB = [props.MeanIntensity];
  1 Comment
Stephen Otieno
Stephen Otieno on 16 Apr 2020
Hi image Analyst, Im not quiet confident using hsv and would like a clarification on "then threshold the s channel to get squares". Currenly I have been using Lab and I have attached my code(2), I've so far been able to select each colour and Im wonder if you've got suggestion on what my next step will be.

Sign in to comment.


Image Analyst
Image Analyst on 16 Apr 2020
OK Stephen, sorry for the delay - you've probably already solved it by now, but for what it's worth, here's a full blown demo for you:
% Demo to mask square tiles and measure their mean RGB from an RGB image. By Image Analyst, April 16, 2020.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
% Read in image.
folder = pwd;
baseFileName = 'org_1.png';
fullFileName = fullfile(folder, baseFileName);
rgbImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the original image.
h1 = subplot(1, 2, 1);
imshow(rgbImage, []);
axis('on', 'image');
caption = sprintf('Original Color Image\n"%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
hFig = gcf;
hFig.Units = 'Normalized';
hFig.WindowState = 'maximized';
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
hFig.Name = 'Demo by Image Analyst';
hFig.NumberTitle = 'Off'
hsvImage = rgb2hsv(rgbImage);
mask = hsvImage(:, :, 2) > 0.25; % Only consider really vivid pixels, not gray ones.
% Fill noise holes
mask = imfill(mask, 'holes');
% Get the areas
% props = regionprops(mask, 'Area');
% areas = sort([props.Area], 'Descend')
% Take the 16 biggest blobs:
mask = bwareafilt(mask, 16);
mask = bwareaopen(mask, 1000); % Remove noise.
% Display the image.
h2 = subplot(1, 2, 2);
imshow(mask);
axis('on', 'image');
title('Mask Image of Square Tiles', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Get red means
propsR = regionprops(mask, redChannel, 'MeanIntensity', 'Centroid');
allMeansR = [propsR.MeanIntensity];
% Get green means
propsG = regionprops(mask, greenChannel, 'MeanIntensity', 'Centroid');
allMeansG = [propsG.MeanIntensity];
% Get red means
propsB = regionprops(mask, blueChannel, 'MeanIntensity', 'Centroid');
allMeansB = [propsB.MeanIntensity];
% Print the values
for k = 1 : length(propsR)
caption = sprintf('Tile %d', k);
% First on the color image.
text(h1, propsR(k).Centroid(1), propsR(k).Centroid(2), caption, ...
'Color', 'k', 'FontSize', 20, 'HorizontalAlignment', 'center');
% Then on the mask
text(h2, propsR(k).Centroid(1), propsR(k).Centroid(2), caption, ...
'Color', 'b', 'FontSize', 20, 'HorizontalAlignment', 'center');
fprintf('For Tile #%2.2d, Mean RGB = (%.3f, %.3f, %.3f).\n', ...
k, allMeansR(k), allMeansG(k), allMeansB(k));
end
msgbox('Done!');
For Tile #01, Mean RGB = (244.618, 57.526, 21.911).
For Tile #02, Mean RGB = (244.867, 57.693, 21.614).
For Tile #03, Mean RGB = (244.857, 229.460, 43.958).
For Tile #04, Mean RGB = (43.470, 15.524, 245.138).
For Tile #05, Mean RGB = (244.845, 57.584, 21.808).
For Tile #06, Mean RGB = (152.526, 244.603, 124.558).
For Tile #07, Mean RGB = (152.184, 244.773, 124.323).
For Tile #08, Mean RGB = (152.723, 244.814, 124.676).
For Tile #09, Mean RGB = (43.232, 15.108, 244.669).
For Tile #10, Mean RGB = (244.858, 229.398, 44.333).
For Tile #11, Mean RGB = (43.118, 15.633, 245.012).
For Tile #12, Mean RGB = (245.048, 57.044, 21.543).
For Tile #13, Mean RGB = (43.727, 15.511, 245.031).
For Tile #14, Mean RGB = (244.918, 57.757, 21.881).
For Tile #15, Mean RGB = (42.992, 15.314, 244.726).
For Tile #16, Mean RGB = (42.924, 15.437, 244.618).
Note the labeling order is in the usual way blobs are ordered: top down, then from left to right. So the ordering might not be what you expect because some squares have a little spur (due to noise) that sticks out on the left side which might cause it to be encountered and measured before a square above it.
  2 Comments
Stephen Otieno
Stephen Otieno on 17 Apr 2020
Thanks for your help image analyst.
I have similar images that are distored and im wondering if you've any tips or demos on how to correct the image back to its original shape.
Image Analyst
Image Analyst on 18 Apr 2020
I'd first segment the black spots, then use imwarp() to put the spots in known locations in the corners. I don't have demo code for that so you're on your own. You might try this link.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!