Adjacent and non-adjacent superpixels for an superpixel in an image
In answers to this question on MATLAB Answers it is hinted that graycomatrix
is a good way to solve this problem. However, those answers are incomplete.
graycomatrix
requires several arguments to do what we need it to do. It computes a gray-value co-occurrence matrix. This is a matrix that says, in cell (i,j)
, how often a gray-value i
occurs next to another gray-value j
. The "next to" relationship can be defined in this function. By default, graycomatrix
returns an 8x8 matrix, where it bins all gray-values in the image into 8 bins, and looks for any gray-value in group i
occurring next to any gray-value in group j
.
So we need to keep each label in our superpixel image separate in this co-occurrence matrix (there are N
different labels, or gray-values). We also need to specify the "next to" relationship to be either [1,0]
or [0,1]
, i.e. two pixels next to each other horizontally or vertically. When specifying two "next to" relations, we get two co-occurrence matrices back, in the form of a 3D matrix. Note also that the co-occurrence matrix is not symmetric, in our superpixel image, label i
might happen to the left of label j
, but in that case it is unlikely that j
also happens to the left of i
. Therefore, glcms(i,j)
would have a non-zero count, but glcms(j,i)
would be zero. In the code below we overcome this by explicitly making the matrix symmetric.
This is the code:
B = imread('kobi.png'); % using one of MATLAB's standard images
[L,N] = superpixels(B,200);
glcms = graycomatrix(L,'NumLevels',N,'GrayLimits',[1,N],'Offset',[0,1;1,0]);
glcms = sum(glcms,3); % add together the two matrices
glcms = glcms + glcms.'; % add upper and lower triangles together, make it symmetric
glcms(1:N+1:end) = 0; % set the diagonal to zero, we don't want to see "1 is neighbor of 1"
glcms
is now the adjacency matrix. The value at glcms(i,j)
is non-zero if superpixels i
and j
are neighbors. The value indicates how large the boundary between the two superpixels is.
To compute an adjacency list:
[I,J] = find(glcms); % returns coordinates of non-zero elements
neighbors = [J,I]
here I use peppers.png as an example image. The pixels in neighboring superpixel are depicted in maskNeighb
variable. The only issue was adjusting parameters for graycomatrix. Perhaps you'll need different parameters for your image, but this should get you started. In the plot, the superpixel chosen should appear black, and the neighbors white.
B = imread('peppers.png');
% make superpixels
[L,N] = superpixels(B,200);
% find neighbors for all superpixels
glcms = graycomatrix(L,'NumLevels',N,'GrayLimits',[],'Symmetric',true);
% find superpixels k neighboring superpixel number 50
supNum = 50;
k=find(glcms(:,supNum));
k(k == supNum) = [];
% find pixels that are in superpixel 50
maskPix = L == supNum;
% find pixels that are in neighbor superpixels k
maskNeighb = ismember(L,k);
% plot
maskPix3 = repmat(maskPix,1,1,3);
maskNeighb3 = repmat(maskNeighb,1,1,3);
Bneigbors = B;
Bneigbors(maskPix3) = 0;
Bneigbors(maskNeighb3) = 255;
figure;
imshow(Bneigbors)