5

After segmenting an image into N superpixels, I need to specify the superpixels that are adjacent or non-adjacent to one superpixel and determine this relationship for all superpixels.

[L,NumLabels] = superpixels(A,200);

How can I specify the adjacent superpixels for each of superpixels ?

Update

I have tried the solution @Cris Luengo introduced. However the following errors arised :

B=imread('H.jpg');
[L,N] = superpixels(B,200);
glcms=graycomatrix(L);
k=glcms(:,50);    %SupNum=50
[r,~]=find(k>0); 
aa=find(r==50);
r(aa)=[];

Error

Update 2 I followed the instruction in MATLAB help but it doesn't work for me. For SupNum=8 the following result has produced:

Output

dtr43
  • 135
  • 7
  • 19
  • 3
    The best way to specify the relationship is through a graph representation. See here: https://www.mathworks.com/help/matlab/ref/graph.html – Cris Luengo Mar 02 '19 at 17:20
  • 2
    Or did you want to know how to determine which superpixels are neighbors? Something like [this](https://www.mathworks.com/matlabcentral/answers/336813-how-do-we-know-what-are-the-superpixels-connected-to-each-other)? – Cris Luengo Mar 02 '19 at 18:55
  • 2
    This one also came up in a search: https://www.mathworks.com/matlabcentral/fileexchange/16938-region-adjacency-graph-rag – Cris Luengo Mar 02 '19 at 19:08
  • Thanks for your help. – dtr43 Mar 02 '19 at 19:32
  • @CrisLuengo,Although it still doesn't work; the main question is that according to the second link you suggested, the **SupNum** variable indicates the superpixel we want to find its neighbors. Why it should not exceed 8 while we have more superpixels. The MATLAB documentation says nothing about that. – dtr43 Mar 07 '19 at 13:24
  • 1
    Specifying [`NumLevels`](https://www.mathworks.com/help/images/ref/graycomatrix.html#bu3j4f2-1-NumLevels) didn't help at all? – beaker Mar 09 '19 at 18:29
  • @beaker , Thanks for you comment, With using **NumLevels**, The results is still incorrect. – dtr43 Mar 09 '19 at 19:20
  • 1
    This might be a good time to post a [mcve]. Otherwise, it's all but impossible to know where the problem is. – beaker Mar 09 '19 at 19:31
  • @beaker ,With using **NumLevels** in the `[glcms,SI] = graycomatrix(L,'NumLevels',N,'GrayLimits',[]);` that **N** is the number of a superpixel that we want specify its neighbors, the error of "_Index in position 3 exceeds array bounds (must not exceed 1)"_ occurs and that is related to the line of `k=glcms(:,:,20); %if you want to find neibours of 1,then input SupNum=1`. – dtr43 Mar 09 '19 at 19:44

2 Answers2

6

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]
Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
3

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)
Yuval Harpaz
  • 1,416
  • 1
  • 12
  • 16
  • 1
    I was not aware of the `'Symmetric'` flag, that's nice. But you're missing specifying the `'Offset'` array, by default it only looks at horizontal neighbors. If two superpixels only have a horizontal boundary between them, then their pixels are neighbors vertically, never horizontally, and this code will not identify the superpixels as neighbors. – Cris Luengo Mar 10 '19 at 07:39
  • 1
    By the way, this question has been up for more than a week, what is the chance that we were typing our answers at the same time? :) – Cris Luengo Mar 10 '19 at 07:41