mlampros / SuperpixelImageSegmentation

Image Segmentation using Superpixels, Affinity Propagation and Kmeans Clustering
https://mlampros.github.io/SuperpixelImageSegmentation/
18 stars 6 forks source link

Testing with different input images is giving the same output images #1

Closed smone00 closed 5 years ago

smone00 commented 5 years ago

Hi, Thanks for this application. If the input image is a different image, the output is still the same as shown in the example images (for a flower image, the output is the same plane image)

Why? What should I do to solve this problem?

mlampros commented 5 years ago

@smone00 I'm sorry for the late reply, could you please show me the code that you use so that I'm able to reproduce it.

smone00 commented 5 years ago

Thanks. I have only changed the name "airplane.jpg" as "flower.jpg", but the result is still the airplane. I am new to R language and tried to compile the script file, but could not solve

The codes are below (they are the same as given at the website)

path_km = system.file("images", "airplane.jpg", package = "SuperpixelImageSegmentation")

im_km = OpenImageR::readImage(path_km)

OpenImageR::imageShow(im_km) spx_km = init$spixel_segmentation(input_image = im_km, superpixel = 600, AP_data = TRUE, use_median = TRUE, sim_wL = 3, sim_wA = 10, sim_wB = 10, sim_color_radius = 10, kmeans_method = "kmeans", kmeans_initializer = "kmeans++", kmeans_num_init = 3, kmeans_max_iters = 100, verbose = TRUE)

str(spx_km) OpenImageR::imageShow(spx_km$AP_image_data)

mlampros commented 5 years ago

The following line of code


path_km = system.file("images", "airplane.jpg", package = "SuperpixelImageSegmentation")

accesses the "airplane.jpg" file in the "images" folder. Most of the R users (like myself), who organize their code in R packages place those images in the "inst" directory of the R package, so that they are accessible. I only have included two images in the "images" folder ('BSR_bsds500_image.jpg' and 'airplane.jpg'). If you want to load your own image then you should try uploading it directly from the folder that you saved it,


path_km = "/your_folder/flower.jpg"
smone00 commented 5 years ago

Thanks for your quick response.

I have tried the second error by myself since I know you are busy and may not have enough time. Howeever, I could not solve it and need your help again.

The error is "Error: object 'init' not found" OpenImageR ClusterR and SuperpixelImageSegmentation packets have been installed. I can see the "init.c" file in the src folder.

Could you please help me to solve this problem.

Another thing is: I want to perfom a grayscale image clustering and segmentation (into 3 or 4 clusters) by using 1) Gaussian mixture model 2) Kmeans 3) SuperpixelImageSegmentation

Could you please share codes that achieve this with an example grayscale image

Thanks again

smone00 commented 5 years ago

For the Gaussian mixture model based clustering, I have tried ClusterR but I got the following error due to very close gray level values and huge black background;

"the determinant is zero or approximately zero. The data might include highly correlated variables or variables with low variance"

To overcome this problem, I have put this ; if (tmp_determinant == 0.0) { (tmp_determinant == 1.0e-8) } into the following header file; ClusterR/inst/include/ClusterRHeader.h

But, I still got the same error message :((

smone00 commented 5 years ago

Dear Lampros,

Okay, I have just solved the problem about the "init" object for the SuperpixelImageSegmentation. I have just seen the following code in the example in your blog site and added ; init = Image_Segmentation$new()

Now, the error is; Error in image_segmentation(input_image, method, superpixel, kmeans_method, : Error converting object to arma::Cube: Input array must have exactly 3 dimensions.

due to the grayscale input image that I am using.

How should I edit the code to achive the SuperpixelImageSegmentation ? Please help me :(

mlampros commented 5 years ago

Hi @smone00,

you receive the error


"Error: object 'init' not found"

because you probably forgot to run first,

init = Image_Segmentation$new()

It isn't related with the 'init.c' file in the 'src' folder.

The 'init$spixel_segmentation' method of the 'Image_Segmentation' R6 class ( Image_Segmentation$new() ) receives only 3-dimensional images ( you can see also the Rcpp code : arma::cube input_image ).

Although the superpixels method is meant for 3-dimensional images you can work with gray-scale images too (indirectly by creating a 3-dim image from a 2-dim one). The following code chunk explains how this can be done (this can be used as a reference for future users of the package too),

library(SuperpixelImageSegmentation)

path = system.file("images", "BSR_bsds500_image.jpg", package = "SuperpixelImageSegmentation")

# 3-dim image

im = OpenImageR::readImage(path)

OpenImageR::imageShow(im)

# convert to gray-scale [ or use directly a gray-scale image ]

gray_scale = OpenImageR::rgb_2gray(im)

dim(im)
dim(gray_scale)

OpenImageR::imageShow(gray_scale)

# convert the image to 3-dim because both 'spixel_segmentation' and  'superpixels' expect a 3-dim image

conv_to_3d = OpenImageR::List_2_Array(list(gray_scale, gray_scale, gray_scale))

dim(conv_to_3d)

OpenImageR::imageShow(conv_to_3d)

init = Image_Segmentation$new()

# image segmentation [ adjust the parameters if necessary ]

num_spix = 200

spx = init$spixel_segmentation(input_image = conv_to_3d, 
                               superpixel = num_spix, 
                               AP_data = TRUE,
                               use_median = TRUE, 
                               sim_color_radius = 10)

str(spx)

OpenImageR::imageShow(spx$AP_image_data[, , 1])      # get only the first image-channel

# build and plot the slico ( for illustration )

res_slico = OpenImageR::superpixels(input_image = conv_to_3d,
                                    method = "slico",
                                    superpixel = 200, 
                                    return_slic_data = TRUE,
                                    return_labels = TRUE, 
                                    write_slic = "", 
                                    verbose = TRUE)

str(res_slico)

plot_slico = OpenImageR::NormalizeObject(res_slico$slic_data[, , 1])      # get only the first image-channel
plot_slico = grDevices::as.raster(plot_slico)
graphics::plot(plot_slico)
mlampros commented 5 years ago

@smone00, I wouldn't recommend to modify the minimum 'determinant' value. The problem lies in your data. An option would be to multiply your data with a big value to overcome this issue.