2

Im trying to segment an image using SLIC in OpenCV. Im trying to use the following function:

void vl_slic_segment    (   vl_uint32 *     segmentation,
float const *   image,
vl_size     width,
vl_size     height,
vl_size     numChannels,
vl_size     regionSize,
float   regularization,
vl_size     minRegionSize 
)

the #include is fine and the linking to libraries is fine. I just need to know how can I pass the image to this function. the image parameter in this function is of type float const * and I dont know how to convert the image to this type.

Here is how i am loading the image into the code:

IplImage *image = cvLoadImage("train.tif", 1);

and here is the whole code:

extern "C" {
  #include </home/me/Downloads/vlfeat-0.9.17/vl/slic.h>
}
#include <stdio.h>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include<opencv/highgui.h>

using namespace std;
using namespace cv;

int main () {
    IplImage *image = cvLoadImage("train.tif", 1);

   vl_uint32 * seg;

   vl_slic_segment(seg,(const float *)image,image->width,image->height,image->nChannels,15,0.1,1);

  waitKey(0);
}

and also i dont know if i am using the vl_uint32 * seg correctly. Please if someone has an example or sample code to do this segmentation.

Thanks !!

triple13
  • 35
  • 6

2 Answers2

3

don't pass the whole image, only the pixels ! and please use the c++ api, not the old c one.

Mat img = imread("train.tif", 1); // 0 for grayscale
Mat floatimg;
img.convertTo(CV_32FC3,floatimg); // CV_32FC1 for grayscale

vl_slic_segment(seg,(const float *)(floatimg.data),floatimg.cols,floatimg.rows,floatimg.channels(),15,0.1,1);
berak
  • 39,159
  • 9
  • 91
  • 89
  • You could also use `floatimg.ptr()` for the second parameter to get rid of that nasty cast. :) – Aurelius Aug 27 '13 at 15:48
  • thanks guys @berak @Aurelius..but it did not work..i tried to debug the program and i got a segmentation fault: `0xb7ead9bb mov %edi,(%ecx)` by the way the image size is 1024 *1024..is there something i should do with the variable `seg` ?? – triple13 Aug 27 '13 at 16:06
  • @triple13 Did you see my answer? `seg` must point to some pre-allocated block of memory. – Aurelius Aug 27 '13 at 16:12
  • @Aurelius yes i just saw it and im trying it...i will let u know..thanks a lot :) – triple13 Aug 27 '13 at 16:16
3

You need to allocate storage for seg correctly. If you are going to use the C++ API as in berak's answer, (which I also recommend) you could create a Mat to hold the label data to make later access easier and automatically manage memory:

cv::Mat labels(floatimg.size(), CV_32SC1); // Mat doesn't support 32-bit unsigned directly, but this should work fine just to hold data.
vl_slic_segment(labels.ptr<vl_uint32>(),floatimg.ptr<float>(),floatimg.cols,floatimg.rows,floatimg.channels(),15,0.1,1);

If for some reason you don't want to do that, you would allocate a chunk of raw memory like this (not recommended):

vl_uint32* seg = new vl_uint32[floatimg.total()]; // don't forget to delete[]

Or if you decide to continue with the C API, you would use malloc (really not recommended):

vl_uint32* seg = (vl_uint32*)malloc(img->height * img->width); // don't forget to free()
Aurelius
  • 11,111
  • 3
  • 52
  • 69
  • @Aurelius..well it seems to work :)..but is there a way to see the segmented photo??..I mean the result..thanks again :) – triple13 Aug 27 '13 at 16:26
  • @triple13 Yes, depending on what you want. You could call `imshow()` on the `labels` image to see the labels generated. Anything more is really outside the scope of this question. Also, if either my or berak's answer helped, would you click the green check mark to accept it? It's a good way to say "thanks" and indicate that a solution was found. – Aurelius Aug 27 '13 at 16:43
  • @Aurelius..yes i already did thanks so much :) the image appears to be black but i will figure a way to show it correctly. – triple13 Aug 28 '13 at 07:58