<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 19, 2016 at 4:05 PM, Moritz Lennert <span dir="ltr"><<a href="mailto:mlennert@club.worldonline.be" target="_blank">mlennert@club.worldonline.be</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 19/12/16 09:38, Rashad Kanavath wrote:<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
<br>
<br>
On Sun, Dec 18, 2016 at 2:53 PM, Moritz Lennert<br></span><span class="">
<<a href="mailto:mlennert@club.worldonline.be" target="_blank">mlennert@club.worldonline.be</a> <mailto:<a href="mailto:mlennert@club.worldonline.be" target="_blank">mlennert@club.worldonl<wbr>ine.be</a>>> wrote:<br>
<br>
    On 18/12/16 14:01, Rashad Kanavath wrote:<br>
<br>
        Hello,<br>
<br>
        As promised, I had pushed code to G7 addons repo<br>
<br>
        <a href="https://trac.osgeo.org/grass/browser/grass-addons/grass7/imagery/i.superpixels.slic" rel="noreferrer" target="_blank">https://trac.osgeo.org/grass/b<wbr>rowser/grass-addons/grass7/ima<wbr>gery/i.superpixels.slic</a><br>
        <<a href="https://trac.osgeo.org/grass/browser/grass-addons/grass7/imagery/i.superpixels.slic" rel="noreferrer" target="_blank">https://trac.osgeo.org/grass/<wbr>browser/grass-addons/grass7/im<wbr>agery/i.superpixels.slic</a>><br>
        <<a href="https://trac.osgeo.org/grass/browser/grass-addons/grass7/imagery/i.superpixels.slic" rel="noreferrer" target="_blank">https://trac.osgeo.org/grass/<wbr>browser/grass-addons/grass7/im<wbr>agery/i.superpixels.slic</a><br>
        <<a href="https://trac.osgeo.org/grass/browser/grass-addons/grass7/imagery/i.superpixels.slic" rel="noreferrer" target="_blank">https://trac.osgeo.org/grass/<wbr>browser/grass-addons/grass7/im<wbr>agery/i.superpixels.slic</a>>><br>
<br>
<br>
    Great job, thanks a lot !<br>
<br>
<br>
        I had tested with some small datasets and is working.<br>
<br>
        More testing welcome :)<br>
<br>
<br>
    I get the following warning during installation:<br>
<br>
    main.c: In function ‘main’:<br>
    main.c:514:13: warning: implicit declaration of function ‘min’<br>
    [-Wimplicit-function-declarati<wbr>on]<br>
         seedx = min(g_width-1,seedx);<br>
                 ^~~<br>
<br>
    I think you have to explicitely define min() through a macro, or<br>
    AFAIK you can use fmin() as elsewhere in the code.<br>
<br>
<br>
I will push a fix for that.<br>
</span></blockquote>
<br>
Thanks, but your fix creates another error:<br>
<br>
main.c: In function ‘main’:<br>
main.c:514:18: error: expected expression before ‘double’<br>
     seedx = fmin(double (g_width-1), seedx);<br>
                  ^~~~~~<br>
main.c:514:13: error: too few arguments to function ‘fmin’<br>
     seedx = fmin(double (g_width-1), seedx);<br>
             ^~~~<br>
In file included from /usr/include/features.h:364:0,<br>
                 from /usr/include/stdio.h:27,<br>
                 from main.c:21:<br>
/usr/include/x86_64-linux-gnu/<wbr>bits/mathcalls.h:360:1: note: declared here<br>
 __MATHCALLX (fmin,, (_Mdouble_ __x, _Mdouble_ __y), (__const__));<br>
 ^<br>
make: *** [OBJ.x86_64-pc-linux-gnu/main.<wbr>o] Erreur 1<br>
<br>
as 'double' is not a function, so double(g_width-1)) doesn't make sense.<br>
<br>
If you want to cast g_width-1 to double before submitting it to fmin(), then AFAIK this would have to be:<br>
<br>
seedx = fmin ((double) (g_width-1), seedx)<br>
<br>
However, again AFAIK, this type conversion is done implicitely anyhow, so you can just write:<br>
<br>
seedx = fmin (g_width-1, seedx)<span class=""><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
    Also:<br>
<br>
    - The output as it is now is not very useful. What we would need is<br>
    a map with each pixel containing the label of the superpixel it<br>
    belongs to. In the original code, there are both outputs: i) an<br>
    image of the superpixel limits overlayed over the original image,<br>
    ii) the labeled pixels<br>
<br>
<br>
you need contour segments as seperate output and also the current one.<br>
right?<br>
</blockquote>
<br></span>
I don't know what you understand by 'contour segments'. What we would need would be an output similar to that of i.segment, i.e. each pixel having the id of the superpixel it belongs to (and there would be no specific boundary pixels).<br>
<br>
The current output is actually not useful at all for us, I think. It is used for visualisation purposes in the original software, but in GRASS we can just vectorize the superpixels if we want to display their contours on top of the original image.<br>
<br>
This means you can just get rid of the entire boundary detection part (lines 730-817 IIUC), and just output the klabels array to a map. Something like this seems to do the job (cf superpixel_id_output.png):<br>
<br>
        int r, z;<br>
        CELL *ubuff[nrows];<br>
        for(  r = 0; r < nrows; r++ )<br>
        {<br>
                ubuff[r] = Rast_allocate_c_buf();<br>
        }<br>
<br>
        z = 0;<br>
        for (y = 0; y < nrows; y++)<br>
        {<br>
                for(x = 0; x < ncols; x++)<br>
                {<br>
                        ubuff[y][x] = klabels[z]+1; /* +1 to avoid category value 0*/<br>
                        z++;<br>
                }<br>
        }<br>
<br>
    outfd = Rast_open_new(result, CELL_TYPE);<br>
<br>
        for (z = 0; z < nrows; z++)<br>
        {<br>
        Rast_put_row(outfd, ubuff[z], CELL_TYPE);<br>
        }<br>
<br>
        for (z = 0; z < nrows; z++)<br>
        {<br>
                G_free(ubuff[z]);<span class=""><br>
        }<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
    - Linked to the above: currently the superpixel boundaries are two<br>
    pixels wide. A one-pixel boundary would be enough.<br>
<br>
<br>
you can adjust no of superpixels with k. default now is 200<br>
</blockquote>
<br></span>
Yes, but this is not what I am talking about.<br>
<br>
Here's an example with the NC demo dataset:<br>
<br>
g.region rast=lsat7_2002_10 -p<br>
i.superpixels.slic red=lsat7_2002_30 green=lsat7_2002_20 blue=lsat7_2002_10 iter=500 k=500 output=superpixels<br>
d.rgb red=lsat7_2002_30 green=lsat7_2002_20 blue=lsat7_2002_10<br>
d.rast map=superpixels values=1<br>
<br>
Then zoom in close, and look at the boundaries (see <a href="http://superpixels_large_boudaries.pn">superpixels_large_boudaries.pn</a><wbr>g attached). You can see that the boundary is at least 2 pixels wide. I would expect a one-pixel boundary to be enough.<br>
<br>
But this is actually not very important since, as mentioned above, the output with the boundaries is not really useful IMHO.<span class=""><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
    - I don't know the details of the algorithm well enough, but would<br>
    it be possible to extend it beyond the use of r,g,b maps as input.<br>
    Ideally, the use should be able to provide a group as input and all<br>
    maps in the group are used in the definition of the superpixels.<br>
    This should also include the case when you only have one band (e.g.<br>
    black and white orthophoto).<br>
<br>
<br>
I need help in understanding this part. because in code, it operates on<br>
lab color space. first it takes RBG and convert to LAB. This is reason,<br>
I had to put red,green,blue parameters.<br>
</blockquote>
<br></span>
I think that the authors come more from pattern recognition in images, and link that pattern recognition to human recognizable color space. And LAB color space is considered closer to human perception.<br>
<br>
After perfunctory reading of their technical paper and a glance over the code, however, I don't really see any reason why going through LAB color space would be necessary.<br>
<br>
I think you can just skip the whole translation to LAB space part and use as many bands as you wish. The only difference would be that you would use kseedsl, kseedsa, kseedsb, but as many kseedsN as you have bands (possibly an array of arrays with N arrays of seed arrays where N is the number bands), and spectral distance would be calculated not by<br>
<br>
dist =  (L[i] - kseedsl[n])*(L[i] - kseedsl[n]) +<br>
        (A[i] - kseedsa[n])*(A[i] - kseedsa[n]) +<br>
        (B[i] - kseedsb[n])*(B[i] - kseedsb[n]);<br>
<br>
but through the equivalent for whatever number of bands you have.<br>
<br>
So, for me, the next steps would be:<br>
<br>
- implementation of id output as above<br>
- implementation of the algorithm using any number of bands (without going through the LAB color space)<br>
- implementation of user defined compactness, and, better yet, SLICO, i.e. automatic detection of compactness. More info and the source code of that are at the bottom of <a href="http://ivrl.epfl.ch/research/superpixels" rel="noreferrer" target="_blank">http://ivrl.epfl.ch/research/s<wbr>uperpixels</a>.<span class="HOEnZb"><font color="#888888"><br>
<br></font></span></blockquote><div><br></div><div>Thanks for your input on this. It is really helpful to me. I will continue to work on this and let you know when I push next version on addons.<br><br></div><div>Hopefully next weekend. <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
<br>
Moritz<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div><font face="arial, helvetica, sans-serif">Regards,<br>   Rashad</font></div></div>
</div></div>