label2rgb problem: 4D to avi cdata

3 views (last 30 days)
D on 7 Jul 2011
Hello Matlab, I am now working on presenting bwlabeled stacks (image sequences)as avi movies. I have some code which converts the series into a format which is usable. I am using the label2rgb3d function from the exchange in my code, since I want to label every labeled object in 3d (using bwlabeln) as its own color. Normally, label2rgb only works on 2d images or arrays, and I have objects which are living in Z as well as X and Y.
When I try to send to images to frame (im2frame) I get this error returned:
Movie cdata must have 2 or 3 dimensions.
I understand matlabs's shortcomings to 4d data handling,yet is there a way to take labeled, colored objects into a movie?
Is there a way label2rgb can be told that objects in 3d are to be labeled the same color?

Accepted Answer

Sean de Wolski
Sean de Wolski on 7 Jul 2011
I'm able to get an RGB movie of a labeled rgb image volume using this:
movie2avi(immovie(V),'Test1'); %to write the movie (V is the volume)
The function I just wrote to get V is below. It accepts a CC struct, not a label image. If you want to get your label image into a CC struct you can either call bwconncomp directly or use my FEX:label2CC
function X = CC2RGB3(CC,cdata)
%Function to take a three dimensional CC struct and turn it into a 4D rgb volume
%SCd - 07/07/2011
%Usage: CC2RGB3(CC)
% CC2RGB3(CC,cdata)
%Input Arguments:
% -CC: output from bwconncomp of a 3d binary image
% -cdata: optional nx3 colormap where each row is the uint8 RGB color to be used
%Output Arguments:
% X: 4-dimensional RGB image
%See Also: bwconncomp bwlabeln colormap
%Error checking:
assert(nargin==1||nargin==2,'One or Two input arguments expected');
assert(isstruct(CC),'The first input argument, CC, is expected to be a struct');
assert(all(ismember({'ImageSize','NumObjects','Connectivity','PixelIdxList'},fieldnames(CC))),'CC is expected to be the output of bwconncomp');
assert(length(CC.ImageSize)==3,'The volume creating CC was expected to by 3-d');
%Take care of cdata:
if nargin == 1;
cdata = makeCdata(CC.NumObjects);
elseif size(cdata,2)~=3
warning('Not:nx3','cdata is expected to be nx3; random will be used');
cdata = makeCdata(CC.NumObjects);
elseif size(cdata,1)<CC.NumObjects
warning('Too:Short','cdata not big enough; random will be used');
cdata = makeCdata(CC.NumObjects);
%Make Volume:
szX = [CC.ImageSize(1),CC.ImageSize(2),3,CC.ImageSize(3)];
X = zeros(szX,'uint8');
for ii = 1:CC.NumObjects
[r c p2] = ind2sub(CC.ImageSize,CC.PixelIdxList{ii}); %probably could be vectorized
rgb_idx = repmat(1:3,size(r,1),1);
idxr = sub2ind(szX, r, c, rgb_idx(:,1), p2);
X(idxr) = cdata(ii,1);
idxg = sub2ind(szX, r, c, rgb_idx(:,2), p2);
X(idxg) = cdata(ii,2);
idxb = sub2ind(szX, r, c, rgb_idx(:,3), p2);
X(idxb) = cdata(ii,3);
function cdata = makeCdata(n)
for ii = 1:10 %try 10x then accept duplicates
cdata = uint8(rand(n,3)*255);
if size(unique(cdata,'rows'),1) == n
D on 8 Jul 2011
I resolved the issue, it was the data structured from previous operations, thank you again. I owe you a beer.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by