dahtah / imager

R package for image processing
GNU Lesser General Public License v3.0
187 stars 43 forks source link

Normalising images using intensities in each channel #88

Open Nova-Scotia opened 5 years ago

Nova-Scotia commented 5 years ago

Hello there,

I'm trying to replicate steps taken by Norouzzadeh et al. (appendix here to normalise an image.

They used tensorflow in python to

"Linearly scale an image to have zero mean and unit variance."

The tensorflow package function is tf.image.per_image_standardization().

According to the package documentation the function:

computes (x - mean) / adjusted_stddev, where mean is the average of all values in image, and adjusted_stddev = max(stddev, 1.0/sqrt(image.NumElements())). stddev is the standard deviation of all values in image. It is capped away from zero to protect against division by 0 when handling uniform images.

I'm trying to achieve the same effect using imager.

I've tried:

iiply(image,"c",function(v) (v-mean(v))/max(sd(v), 1.0/sqrt(length(v)))) %>% plot,

but the resulting image appears to be a less saturated image than the example they provide. Ignore the scaling, sorry!

Original image: image

Desired results according to Norouzzadeh et al. image

My results image

Am I doing something wrong and is it possible to achieve the same results as in the paper I'm looking at?

ShotaOchi commented 5 years ago

It looks like the desired result was saturated. I think you overlooked something else such as equalization. Did you confirm the desired result was made by only tf.image.per_image_standardization() ? By the way, the appendix is missing.

Nova-Scotia commented 5 years ago

Hi @ShotaOchi , thanks for taking a look. I've fixed the link to the appendix (above). The part I am specifically interested in is on page 2, Pre-processing.

Pre-processing. The original images in the dataset are 2,048×1,536 pixels, which is too large for current state-of-the- art deep neural networks owing to the increased computational costs of training and running DNNs on high-resolution images. We followed standard practices in scaling down the images to 256×256 pixels. Although this may distort the images slightly, since we do not preserve the aspect ratios of the images, it is a de facto standard in the deep learning community (1). The images in the dataset are color images, where each pixel has three values: one for each of the red, green, and blue intensities. We refer to all the values for a specific color as a color channel. After scaling down the images, we computed the mean and standard deviation of pixel intensities for each color channel separately and then we normalized the images by subtracting the average and dividing by the standard deviation (Fig. S.1).

After some digging I believe the code they used is here, on the Evolving AI Lab's page. The process I am interested in is what they are doing to the test images, not the training images; the relevant python code is below. It does appear that the only changes are to resize and standardize the image.

I noticed that my values after trying my own standardization (using the code mentioned above) results in many negative values, which seems wrong...

def _test_preprocess(reshaped_image, args):
  # Image processing for evaluation.
  # Crop the central [height, width] of the image.
  resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,
                                                         args.crop_size[0], args.crop_size[1])

  # Subtract off the mean and divide by the variance of the pixels.
  float_image = tf.image.per_image_standardization(resized_image)

  # Set the shapes of tensors.
  float_image.set_shape([args.crop_size[0], args.crop_size[1], args.num_channels])

  return float_image