Asked by Aravin
on 7 Aug 2012

Hi everyone,

I have matrix **R** in which each element is integer of range [0 7]. I want to calculate the count of neighbor, let say for pixel value 0 how many times it has the neighbor 1, 2, ..., 7.
every pixel has eight neighbors, for example

[n1 n2 n3 n4 x n5 n6 n7 n8]

where pixel **x** have eight neighbors. As a resultant I think we will have an other matrix of 8 x 8, or we can say 8 histograms as we have eight possible values in given matrix **R**.

I hope I have explained what I want :-(

Answer by Matt Fig
on 8 Aug 2012

Edited by Matt Fig
on 8 Aug 2012

Accepted answer

If you don't have the image processing toolbox, or if you want your code to be useful to those who don't, this is just as fast. Note that the example only looks for the neighbors of the number 7. You can put this into a loop as needed. I assume your matrix is named x.

H = single(x==7); H = logical(conv2(H,ones(3),'same'))~=H; H = x(H(:)); Y = unique(H); H = histc(H,Y); H = [Y H];

Answer by Sean de Wolski
on 7 Aug 2012

I would take an image processing approach:

x = zeros(5); %sample matrix x(3:5,3:5) = [1 2 1;1 7 2;3 4 1]; x(5) = 7;

BW = x==7; %We'll count neighbors of 7s M = xor(imdilate(BW,ones(3)),BW); %neighbors of 7s uv = unique(x(M)); %unique neighbors n = histc(x(M),uv); %count unique neighbors [uv n] %display number of unique values to occurences

Answer by Andrei Bobrov
on 7 Aug 2012

Edited by Andrei Bobrov
on 8 Aug 2012

A = randi([0 7],10);

A1 = nan(size(A)+2); A1(2:end-1,2:end-1) = A; k = (0:7)'; n = numel(k); out = zeros(n); d = true(3); d(5) = false; for i1 = 1:n [ii,jj] = find(A1 == k(i1)); p = zeros(n,1); for i2 = 1:numel(ii) q = A1(ii(i2) + (-1:1),jj(i2) + (-1:1)); p = p + histc(q(d&(~isnan(q))),k); end out(:,i1) = p; end

variant based on the idea of Sean and Matt:

k = (0:7)'; out = zeros(numel(k)); for a = 1:numel(k) out(:,a) = histc(x(bwdist(x == k(a),'chessboard') == 1),k); end

Sean de Wolski
on 13 Aug 2012

`xor()` from mine or the `~=` from Matt's. We were intentionally not counting the 7, but if you want to count it it makes our solutions even simpler :)

Answer by Teja Muppirala
on 8 Aug 2012

R = randi([0 7],100); % Input

H = zeros(8); % The 8x8 Matrix for k = 0:7 C = conv2(double(R == k),[1 1 1; 1 0 1; 1 1 1],'same'); H(:,k+1) = accumarray(1+R(C~=0),nonzeros(C),[8 1]); end

bar(H);

Opportunities for recent engineering grads.

## 9 Comments

## Image Analyst (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94050

Why do you want to do this? It seems like the gray level co-occurrence matrix (done by graycomatrix() in the Image Processing Toolbox), but not quite. What is the use case? Why do you want the histogram of neighbors, but not including the central pixel? What is the context - the big picture?

## Aravin (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94055

Actually, in my application, each value in

Ris some computed value, whose range is between 0-7. I just want to see the corelation of neighbors of these computed values.## Image Analyst (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94060

Then is there any reason why you're not using the gray level cooccurrence matrix, which is usually what people use?

## Aravin (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94131

Thanks a lot, gray level cooccurrence matrix really a one line solution. Setting offset, I can get the desired results.

Before, I want not using this as I didn't know about this function and Matrix. :-) Thanks.

## Matt Fig (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94132

What command did you use to get the results in one line? Usually I can figure out how things work by reading the documentation, but I have no idea how GRAYCOMATRIX produces the result. Please show the code you used. Thanks!

## Matt Fig (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94164

Nevermind, my copy of GRAYCOMATRIX has a severe bug in it anyway. It doesn't even reproduce the output shown in the doc, so I doubt it would give the desired result here. Bummer!

I will search the FEX and elsewhere for a more reliable implementation.

## Image Analyst (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94174

Granted, their graycomatrix is very confusing and has some weird defaults, and you have to do things to get it to do what you'd intuitively want it to do. For example, it only looks at pairings to the right of the pixel, not all around at all 8 neighbors (unless you pass in the correct "offset" parameter). Matt, try this code and see if you get the tables they show in their explanatory diagram:

## Aravin (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94281

Hi Matt,

Here is the one line solution I did for my problem.

I will have 8 number of channels, which I have sum for final result.

## Matt Fig (view profile)

Direct link to this comment:http://nl.mathworks.com/matlabcentral/answers/45427#comment_94311

Thanks, IA. Indeed you are correct. The illustration I was looking at in the doc seemed to imply it was showing graycomatrix(I).

I see now the difference between what this function gives and what I (and others) showed below. If we have:

Then to get the same result as:

I would modify my code to:

Thus M and G are equal. M took half the time to compute, but the code is definitely longer! Note that the calculation of M could perhaps be made more efficient by storing the x(:)==jj in a cell outside the loop.

Anyway, I'm glad Aravin got what was required.