Question

I have an edge image [gotten by applying canny edge detector]. On this I have a keypoint. I would like to get a histogram of the image with concentric (circular+radial) bins, similar to sectors in a CD or DVD, with the keypoint as the center.

I am planning to do it this way: 1. Apply a binary mask on the edge image 2. Apply circular+radial mask on the image with different radii. 3. Sum up all the pixel values for each radii.

The part I am stuck up is 2. How can I get circular+radial mask at the same time? To make it clearer - assume I have an image - I want to divide it into bins by drawing concentric circles and lines along the radius at period angles.

EDIT

The code provided by @anandr works like a charm with some minor modifications. But, we now have number of Angbins and Radbins, can we club both of them into a set of bins as depicted in the pic I linked here ? The reason is we have to flatten this into a histogram of the number pixel values having the value 1 in each of the bins we are scanning. Is this possible? Please let me know! Thanks!

EDIT 2

For the code that @anandr gave earlier, what if I include

agg(ia,ir)=sum(abs(tImg(:)));

after the tImg = cat(3,tR,tG,tB); part? Will this give me the number of pixels with value 1 in that particular bin?

Was it helpful?

Solution

As @Parag suggested, you have to check distance and angle of each pixel with respect to the key point. Then you can use the histc function to assign proper bin number to your pixels. Check the code below

function [RadialBins,AngularBins] = MakeRadCircMask(ImgRows,ImgCols, KeyRow,KeyCol, DistanceEdges, AngleEdges)
    % [RadialMask,AngularMask] = MakeRadCircMask(ImgRows,ImgCols, KeyRow,KeyCol, DistanceEdges, AngleEdges)
    % RADIALBINS  is the distance bin number for bin edges specified in DISTANCEEDGES
    % ANGULARBINS is the distance bin number for bin edges specified in ANGLEEDGES
    % For pixels outside of min(DISTANCEEDGES):max(DISTANCEEDGES) -1 returned
    % For pixels outside of min(ANGLEEDGES):max(ANGLEEDGES) -1 returned
    x                   = (1:ImgCols)-KeyCol;
    y                   = (1:ImgRows)-KeyRow;
    [xx,yy]             = meshgrid( x , y );
    d                   = sqrt( xx.^2 + yy.^2 );
    a                   = atan2( yy , xx );
    [n,bin]             = histc(d,DistanceEdges);
    RadialBins          = -ones(ImgRows,ImgCols);
    RadialBins(bin>0)   = bin(bin>0);
    [n,bin]             = histc(a,AngleEdges*pi/180);
    AngularBins         = -ones(ImgRows,ImgCols);
    AngularBins(bin>0)  = bin(bin>0);
end

% now we test the masks

%Initial data
ImgRows     = 100;
ImgCols     = 200;
DstEdges    = 0:10:150;
AngEdges    = -180:30:180;

NDstBins    = length(DstEdges)-1;
NAngBins    = length(AngEdges)-1;

%Create checkerboard image
r           = 1:ImgRows;
c           = 1:ImgCols;
[cc,rr]     = meshgrid(c,r);
Img         = (-1).^( round(rr/3) + round(cc/3) );
Img(Img<0)  = 0;

% Calculate bins
[RadialBins,AngularBins] = MakeRadCircMask(ImgRows,ImgCols, 50,150, DstEdges, AngEdges );

% show the cartoon ;o)
figure;
subplot(2,2,1); imagesc(RadialBins);  axis equal; axis tight; title('Radial bins');
subplot(2,2,2); imagesc(AngularBins); axis equal; axis tight; title('Angular bins');
subplot(2,2,3); imagesc(Img);         axis equal; axis tight; title('Original image');
subplot(2,2,4); imagesc(Img);         axis equal; axis tight; title('Selection image');
%return;

for ir=1:NDstBins
    % compute the radiaal mask
    rMask       = RadialBins==ir;

    for ia=1:NAngBins
        % compute the angular mask
        aMask       = AngularBins==ia;

        % do some stuff with the images
        tR              = zeros(ImgRows,ImgCols);
        tG              = zeros(ImgRows,ImgCols);
        tB              = zeros(ImgRows,ImgCols);

        tR(aMask)       = Img(aMask);
        tG(rMask)       = Img(rMask);
        tB(rMask&aMask) = Img(rMask&aMask);
        tR(rMask&aMask) = 0;
        tG(rMask&aMask) = 0;

        tImg            = cat(3,tR,tG,tB);

        % and display the results
        subplot(2,2,4); imagesc(tImg);   axis equal; axis tight;
        title( {
            sprintf('Radial bin  %d of %d (%.1f to %.1f);',ir,NDstBins,DstEdges(ir),DstEdges(ir+1) )
            sprintf('Angular bin %d of %d (%.1f to %.1f);',ia,NAngBins,AngEdges(ia),AngEdges(ia+1) )
            } )
        drawnow;
    end

end

UPD: code updated to handle out-of-range pixels

EDIT1 Modification is easy if you need variable number of angular bins for each radial stripe. In this case, however, sectors of each radial bin are numbered starting from one to appropriate number of angular bins. So if you need to process one particular sector you have to check both radial mask and angular mask.

function [RadialBins,AngularBins] = RadialGrid(ImgRows,ImgCols, KeyRow,KeyCol, DistanceMin,DistanceMax, NAngleBins,NDistanceBins)
    % Grid = RadialGrid(ImgRows,ImgCols, KeyRow,KeyCol, DistanceMin,DistanceMax, NAngleBins,NDistanceBins)
    % for details see http://stackoverflow.com/questions/19485118/creating-a-histogram-of-edge-image-with-concentric-circles-around-one-point-mat/19487198?noredirect=1#comment28938533_19487198
    %
    if ~isscalar(NDistanceBins)
        error( 'NDISTANCEBINS must be scalar' );
    end
    if isscalar(NAngleBins)
    NAngleBins           = ones(1,NDistanceBins)*NAngleBins;
    end
    if length(NAngleBins)~=NDistanceBins
        error( 'NANGLEBINS must be scalar or vector of NDISTANCEBINS elements' );
    end

    DistanceEdges       = linspace(DistanceMin,DistanceMax,NDistanceBins+1);
    x                   = (1:ImgCols)-KeyCol;
    y                   = (1:ImgRows)-KeyRow;
    [xx,yy]             = meshgrid( x , y );
    d                   = sqrt( xx.^2 + yy.^2 );
    a                   = atan2( yy , xx );
    [n,bin]             = histc(d,DistanceEdges);
    RadialBins          = -ones(ImgRows,ImgCols);
    RadialBins(bin>0)   = bin(bin>0);
    RadialBins(RadialBins>NDistanceBins) = -1;
    AngularBins         = zeros(size(RadialBins))-1;
    for kk=1:NDistanceBins
    AngleEdges          = linspace(-180,+180,NAngleBins(kk)+1);
    [n,bin]             = histc(a,AngleEdges*pi/180);
    idx                 = (bin>0) & (RadialBins==kk);
    AngularBins(idx)    = bin(idx);
    end
end

ImgRows         = 400;
ImgCols         = 400;
NDistanceBins   = 5;
NAngleBins      = 2.^(1:NDistanceBins);

%Create checkerboard image
r               = 1:ImgRows;
c               = 1:ImgCols;
[cc,rr]         = meshgrid(c,r);
Img             = (-1).^( round(rr/3) + round(cc/3) );
Img(Img<0)      = 0;

%     [RadialBins,AngularBins] = RadialGrid(ImgRows,ImgCols, ImgRows/2,ImgCols/2, 50,200, 2.^(1:NDistanceBins),NDistanceBins);
%     figure;
%     subplot(2,2,1); imagesc(RadialBins);  axis equal; axis tight; title('Radial bins');
%     subplot(2,2,2); imagesc(AngularBins); axis equal; axis tight; title('Angular bins');
%
%     [RadialBins,AngularBins] = RadialGrid(ImgRows,ImgCols, ImgRows/2,ImgCols/2, 50,200, (1:NDistanceBins)+1,NDistanceBins);
%     subplot(2,2,3); imagesc(RadialBins);  axis equal; axis tight; title('Radial bins');
%     subplot(2,2,4); imagesc(AngularBins); axis equal; axis tight; title('Angular bins');
%     colormap(jet(255));

[RadialBins,AngularBins] = RadialGrid(ImgRows,ImgCols, ImgRows/2,ImgCols/2, 50,200, NAngleBins,NDistanceBins);

% show the cartoon ;o)
figure;
subplot(2,2,1); imagesc(RadialBins);  axis equal; axis tight; title('Radial bins');
subplot(2,2,2); imagesc(AngularBins); axis equal; axis tight; title('Angular bins');
subplot(2,2,3); imagesc(Img);         axis equal; axis tight; title('Original image');
subplot(2,2,4); imagesc(Img);         axis equal; axis tight; title('Selection image');
%return;

for ir=1:NDistanceBins
    % compute the radiaal mask
    rMask       = RadialBins==ir;

    for ia=1:NAngleBins(ir)
        % compute the angular mask
        aMask       = AngularBins==ia;

        % do some stuff with the images
        tR              = zeros(ImgRows,ImgCols);
        tG              = zeros(ImgRows,ImgCols);
        tB              = zeros(ImgRows,ImgCols);

        SectorMask      = rMask&aMask;

        tR(rMask)       = Img(rMask);
        tG(SectorMask)  = Img(SectorMask);
        tB(aMask)       = Img(aMask);
        tImg            = cat(3,tR,tG,tB);

        % and display the results
        subplot(2,2,4); imagesc(tImg);   axis equal; axis tight;
        title( {
            sprintf('Radial bin  %d of %d;',ir,NDistanceBins )
            sprintf('Angular bin %d of %d;',ia,NAngleBins(ir) )
            } )
        drawnow;
    end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top