Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Using histogram to find the frequency of combinations within the data set

Asked by Clifford Shelton on 1 Aug 2012

I am new to Matlab and just started getting into generating histograms. I understand how to create a histogram that determines the frequency of values..

But how can I create a histogram that is looking for specific combinations of data?

For example I have the following data set:

someData = [1,3,4,4,2,1,1,0]

How would I be able to create a histogram that determines the frequency of one value in the data set is exactly equal to the next value within the same dataset??

In the above example the answer should be 2. (4 repeat and are adjacent to each other. 1 repeats and is adjacent to each other)

Help is MOST appreciated!

1 Comment

Clifford Shelton on 1 Aug 2012

I'm so lost...I'm thinking it may look something like this:

 for i=1:8133
      hist ((someData (i)==someData(i+1)/Total)

But I really have no clue AND I'm a beginner. Sorry if this questions seems elementary

Clifford Shelton

Products

No products are associated with this question.

1 Answer

Answer by Image Analyst on 1 Aug 2012

You can do this with the gray level co-occurrence matrix (GLCM). It's done by the function graycomatrix() in the Image Processing Toolbox. It's like a 2D histogram that counts how many times each gray level (numerical value) occurs next to every other gray level (value).

12 Comments

Clifford Shelton on 3 Aug 2012

Yeah..I was studying your BlobsDemo yesterday. I wouldn't have thought about using the image processing toolbox for what I'm trying to do at all! Being that I'm a beginner....I still lack the skill to look at your demo and get the eureka feeling of knowing how to apply it to my specific task.

let's say this is my data set

      dataSet = (1,4,6,2,2,7,8,4,4) 

and I want to calculate the average in values of every three adjacent steps. Yesterday you mentioned: "you'd need to run that through conv() or imfilter() first to get the average in a sliding window, then use regionprops()"

However, I have no clue as to how to apply your suggestion. Some example code to make it clearer would be most appreciated!

Image Analyst on 3 Aug 2012

For an average that moves over by 1 every time, use conv().

dataSet = [1,4,6,2,2,7,8,4,4]
slidingAverage = conv(dataSet, [1 1 1]/3, 'valid')

If you want to move in "jumps" of 3, then you'll have to use blockproc(). Here's a 2D demo for blockproc that you can probably easily adapt to 1D signals if you need to:

function blockproc_demo()
try
	clc; % Clear the command window.
	close all; % Close all figures (except those of imtool.)
	workspace; % Make sure the workspace panel is showing.
	fontSize = 20;
	% Change the current folder to the folder of this m-file.
	if(~isdeployed)
		cd(fileparts(which(mfilename)));
	end
	% Read in standard MATLAB demo image.
	grayImage = imread('cameraman.tif');
	[rows columns numberOfColorChannels] = size(grayImage);
	% Display the original image.
	subplot(2, 2, 1);
	imshow(grayImage, []);
	caption = sprintf('Original Image\n%d by %d pixels', ...
	rows, columns);
	title(caption, 'FontSize', fontSize);
	% Enlarge figure to full screen.
	set(gcf, 'Position', get(0,'Screensize'));
	set(gcf, 'name','Image Analysis Demo', 'numbertitle','off')
	% Block process the image.
	windowSize = 3;
	% Each 3x3 block will get replaced by one value.
	% Output image will be smaller by a factor of windowSize.
	myFilterHandle = @myFilter;
	blockyImage = blockproc(grayImage,[windowSize windowSize], myFilterHandle);
	[rowsP columnsP numberOfColorChannelsP] = size(blockyImage);
	% Display the processed image.
	% It is smaller, but the display routine imshow() replicates
	% the image so that it looks bigger than it really is.
	subplot(2, 2, 2);
	imshow(blockyImage, []);
	caption = sprintf('Image Processed in %d by %d Blocks\n%d by %d pixels\nCustom Box Filter', ...
	windowSize, windowSize, rowsP, columnsP);
	title(caption, 'FontSize', fontSize);
	% Now let's do it an alternate way where we use an anonymous function.
	% We'll take the standard deviation in the blocks.
	windowSize = 8;
	myFilterHandle2 = @(block_struct) ...
	std2(block_struct.data) * ones(size(block_struct.data));
	blockyImageSD = blockproc(grayImage, [windowSize windowSize], myFilterHandle2);
	[rowsSD columnsSD numberOfColorChannelsSD] = size(blockyImageSD);
	subplot(2, 2, 4);
	imshow(blockyImageSD, []);
	caption = sprintf('Image Processed in %d by %d Blocks\n%d by %d pixels\nAnonymous Standard Deviation Filter', ...
	windowSize, windowSize, rowsSD, columnsSD);
	title(caption, 'FontSize', fontSize);
	% Note: the image size of blockyImageSD is 256x256, NOT smaller.
	% That's because we're returning an 8x8 array instead of a scalar.
	uiwait(msgbox('Done with demo'));
	catch ME
		errorMessage = sprintf('Error in blockproc_demo():\n\nError Message:\n%s', ME.message);
		uiwait(warndlg(errorMessage));
	end
	return;
% Takes one 3x3 block of image data and multiplies it
% element by element by the kernel and
% returns a single value.
function singleValue = myFilter(blockStruct)
	try
		% Assign default value.
		% Will be used near sides of image (due to boundary effects),
		% or in the case of errors, etc.
		singleValue = 0;
		% Create a 2D filter.
		kernel = [0 0.2 0; 0.2 0.2 0.2; 0 0.2 0];
		% kernel = ones(blockStruct.blockSize); % Box filter.
		% Make sure filter size matches image block size.
		if any(blockStruct.blockSize ~= size(kernel))
			% If any of the dimensions don't match.
			% You'll get here near the edges,
			% if the image is not a multiple of the block size.
			% warndlg('block size does not match kernel size');
			return;
		end
		% Size matches if we get here, so we're okay.
		% Extract our block out of the structure.
		array3x3 = blockStruct.data;
		% Do the filtering. Multiply by kernel and sum.
		singleValue = sum(sum(double(array3x3) .* kernel));
	catch ME
		% Some kind of problem...
		errorMessage = sprintf('Error in myFilter():\n\nError Message:\n%s', ME.message);
		% uiwait(warndlg(errorMessage));
		fprintf(1, '%s\n', errorMessage);
	end
	return; 
Clifford Shelton on 3 Aug 2012

Thanks for all the example code. I'm learning A LOT through this exchange!! Alas, I'm stuck on applying your example to my data set. I understand what the blockproc does..but I am hazy on what this @myfilter business is.

Here is the code I've attempted to make:

% Block process the data.
	dataChunk = 10;
	% Each 10x1 block will get replaced by one value. 
	% Output data will be smaller by a factor of dataChunk.
	myFilterHandle = @myFilter; % have NO clue here
	groupsOfTen = blockproc(myData,[dataChunk 1], myFilterHandle);

But this causes an error about the 'fun' in the statement. Which I think is related to the @myFilter part that I have NO clue about what it means.

I'm guessing that after I'm able to get this step in the process to work, I then do conv() to get the averages of each value in the output for groupsOfTen?

Help is appreciated!

Image Analyst

Contact us