8
$\begingroup$

I am developing an algorithm to generate a descriptor of a 2D object based on polar histogram. suppose that we have a datalist centered in {cx,cy}. I use 36 bins where I consider 12 angles and 3 different radius (see figure). I tried this code but I did not get the right figure. How can specify just 12 angles and how can we count the point of each sector?

data = {{10, 10}, {20, 20}, {40, 40}, {10, 20}, {100, 2}, {1, 1}, {2, 
    40}, {10, 11}, {12, 13}, {15, 15}, {100, 25}, {112, 12}, {113, 
    114}, {1, 111}};
center={50,50}
centereddata = (# - center) & /@ data;
angles = N[ArcTan[#[[1]], #[[2]]]/Degree] & /@ centereddata
radiis = N@Sqrt[#[[1]]^2 + #[[2]]^2] & /@ centereddata;
ListPolarPlot[Transpose[Join[{angles}, {radiis}]], PolarAxes -> True,
 PolarGridLines -> Automatic,PolarTicks -> {"Degrees", Automatic}]

enter image description here

$\endgroup$
7
  • $\begingroup$ related mathematica.stackexchange.com/q/10923/193 $\endgroup$ Dec 10, 2014 at 4:28
  • 1
    $\begingroup$ related (duplicate?): (31347) $\endgroup$
    – C. E.
    Dec 10, 2014 at 4:38
  • $\begingroup$ @Pickett, thanks. This reference does not count the number of points of each sector. I think it is not possible to specify the number of angles using ListPolarPlot[]. I fond this example stackoverflow.com/questions/7419562/… using the ListPolarPlot[] but it did not specify the angles number. $\endgroup$ Dec 10, 2014 at 5:06
  • $\begingroup$ What's radiis? It's not specified in your code. $\endgroup$
    – Verbeia
    Dec 10, 2014 at 5:51
  • $\begingroup$ @Verbeia, sorry I edited my code. $\endgroup$ Dec 10, 2014 at 6:11

3 Answers 3

10
$\begingroup$

[Edited to correct the bin definition.]

You could use SectorChart. The trick is to ensure that your bin widths sum to 360° and that the first bin charted starts at zero.

Firstly, and borrowing shamelessly from @george2079's answer [and subsequent correction], define the bins:

bins = Table[a , {a, -180, 180, 30}];

Next create the sector chart data:

sData = RotateLeft[
  Tooltip[Join[Differences[#1], {#2}], {Mean[#1], #2}] & @@@ 
   Transpose[{Partition[bins, 2, 1], BinCounts[angles, {bins}]}], 
  FirstPosition[bins, 0] - 1]

{{30, 1}, {30, 8}, {30, 0}, {30, 0}, {30, 2}, {30, 1}, {30, 0}, {30, 1}, {30, 0}, {30, 0}, {30, 1}, {30, 0}}

There are several things going on here:

  • We add a tooltip so that the each sector is labelled with the mid-point of the bin and the count,
  • we calculate the width of each bin and
  • we rotate the data such that the bin starting at zero is first in the list. Obviously this requires a bin edge at zero.

Finally chart it, adding axes, etc. and rotating the origin (thanks again @george2079):

SectorChart[sData, PolarGridLines -> Automatic, 
 PolarTicks -> {Automatic, None}, PolarAxes -> {True, False}, 
 SectorOrigin -> 0]

Sector chart

$\endgroup$
2
  • $\begingroup$ +1 nice, but you "shamelessly" copied my mistake :).. Also BTW SectorOrigin->0 will make this look more like a standard polar plot. $\endgroup$
    – george2079
    Dec 10, 2014 at 20:02
  • $\begingroup$ @george2079 Thanks. I've corrected the bins in my answer too but it was slightly more involved because the sectors are relative. $\endgroup$ Dec 11, 2014 at 10:05
9
$\begingroup$
 data = RandomReal[ {0, 200}, {200, 2}];
 center = {50, 50};
 centereddata = (# - center) & /@ data;
 angles = N[ArcTan[#[[1]], #[[2]]]/Degree] & /@ centereddata;
 radiis = N@Sqrt[#[[1]]^2 + #[[2]]^2] & /@ centereddata;

note you need to use Degree to put the angles back to radians here..

 polardata = Transpose[Join[{angles Degree}, {radiis}]];
 ListPolarPlot[polardata, PolarAxes -> True, 
    PolarGridLines -> Automatic, PolarTicks -> {"Degrees", Automatic}]

enter image description here

 bins = Table[a, {a, -180, 180, 30}];
 bincenters = ( Degree) Mean /@ Partition[ bins , 2, 1];
 hdata = Transpose[{bincenters , BinCounts[angles, {bins}] } ];
 ListPolarPlot[ hdata , PolarAxes -> True, PolarGridLines -> Automatic,
    PolarTicks -> {"Degrees", Automatic},
    Epilog -> {Red, 
    Line[{{0, 0}, #[[2]] {Cos[#[[1]]], Sin[#[[1]]]}}] & /@ hdata}]

enter image description here

ListPolarPlot doesn't evidently have a Filling option, hence the Epilog

... I hope you didn't just want this :)

   Histogram[ 1/Degree First /@ polardata  , {bins}]

enter image description here

edit a bit fancier..

 Epilog -> {Red, {Line[{{0, 0}, #[[2]] {Cos[#[[1]]], Sin[#[[1]]]}}], 
     Circle[{0, 0}, #[[2]], {#[[1]] - 15 Degree, #[[1]] + 15 Degree}]} & /@ 
     hdata}`

enter image description here

$\endgroup$
2
  • $\begingroup$ Thanks, but you had a little mistakes. To get the right histogram, we have to change angles between 0 and 360 because ArcTan[] gives an angle between -180 and 180. newangles = Mod[(angles + 360), 360]; $\endgroup$ Dec 10, 2014 at 19:50
  • $\begingroup$ good catch, fixed it.. $\endgroup$
    – george2079
    Dec 10, 2014 at 19:58
4
$\begingroup$

I propose an example silhouette descriptor based on a polar histogram. In my example histogram consits of 36 bins.

enter image description here

newBinCounts funtion

newBinCounts[angles_, bins_] := Module[{hist, sectorIndex}, (
       hist = BinCounts[angles, {bins}];
       sectorIndex = 
        Table[Flatten[
          Union[Position[angles, #] & /@ 
            Select[angles, bins[[i]] <= # < bins[[i + 1]] &]]], {i, 1, 
          Length[bins] - 1}];
       {hist, sectorIndex}
       )]

polarHistogram function

polarHistogram[regionOfInterest_, anglebins_] := 
 Module[{positionsWhitePixel, centroid, centeredpositionsWhitePixel, 
   angles, bins, raduis, bincenters, histData, sectorIndex, hData, 
   binrad, listOfRadius, listHist}, (

   positionsWhitePixel = 
    PixelValuePositions[regionOfInterest, White];

   Graphics[{Point@positionsWhitePixel}];

   centroid = N@Mean[positionsWhitePixel];


   centeredpositionsWhitePixel = (# - centroid) & /@ 
     positionsWhitePixel;

   angles = 
    Mod[(# + 360), 360] & /@ (N[ArcTan[#[[1]], #[[2]]]/Degree] & /@ 
       centeredpositionsWhitePixel);
   raduis = 
    N@Sqrt[#[[1]]^2 + #[[2]]^2] & /@ centeredpositionsWhitePixel;

   Print[ListPolarPlot[Transpose[Join[{angles Degree}, {raduis}]], 
     PolarAxes -> True, PolarGridLines -> Automatic, 
     PolarTicks -> {"Degrees", Automatic}]];

     bins = Table[i, {i, 0, 360, anglebins}];
   bincenters = (Degree) Mean /@ Partition[bins, 2, 1];
   {histData, sectorIndex} = newBinCounts[angles, bins];
   hData = Transpose[{bincenters, BinCounts[angles, {bins}]}];

   Print[ListPolarPlot[hData, PolarAxes -> True, 
     PolarGridLines -> Automatic, 
     PolarTicks -> {"Degrees", Automatic}, 
     Epilog -> {Red, 
       Line[{{0, 0}, #[[2]] {Cos[#[[1]]], Sin[#[[1]]]}}] & /@ hData}]]
   (*in this code, i consider 3 raduis 0-20,
   20-40,40,200*)
   binrad = {0, 20, 40, 200};
   listOfRadius = raduis[[#]] & /@ sectorIndex;
   listHist = Transpose[BinCounts[#, {binrad}] & /@ listOfRadius];
   listHist
   )]

This function calculate an histogram of 36 bins. (call function using the silhouette)

list3 = polarHistogram[sil3, 30];


 (*list3={{100,103,104,107,104,99,111,104,106,103,104,111},{309,316,311,263,303,309,319,313,316,314,314,319},{1325,2079,132,0,45,359,1741,1674,514,148,53,176}}*)

enter image description here enter image description here

\ https://i.stack.imgur.com/aZmWQ.png

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.