1
votes

I'm using opencv + python to process fundus(retinal images). There is a problem that im facing while converting a float64 image to uint8 image.

Following is the python code:

import cv2
import matplotlib.pyplot as plt
import numpy as np
from tkFileDialog import askopenfilename

filename = askopenfilename()
a = cv2.imread(filename)
height, width, channel = a.shape
b, Ago, Aro = cv2.split(a)
mr = np.average(Aro)
sr = np.std(Aro)

Ar = Aro - np.mean(Aro)
Ar = Ar - mr - sr

Ag = Ago - np.mean(Ago)
Ag = Ag - mr - sr

#Values of elements in Ar
#    Ar = [[-179.17305527, -169.17305527, -176.17305527, ..., -177.17305527, -177.17305527, -177.17305527],
#           [-178.17305527, -169.17305527, -172.17305527, ..., -177.17305527, -177.17305527, -177.17305527],
#           [-179.17305527, -178.17305527, -179.17305527, ..., -177.17305527, -177.17305527, -177.17305527],
#           ...,
#           [-177.17305527, -177.17305527, -177.17305527, ..., -177.17305527, -177.17305527, -177.17305527],
#           [-177.17305527, -177.17305527, -177.17305527, ..., -177.17305527, -177.17305527, -177.17305527],
#           [-177.17305527, -177.17305527, -177.17305527, ..., -177.17305527, -177.17305527, -177.17305527]]

Mr = np.mean(Ar)
SDr = np.std(Ar)

print "MR = ", Mr, "SDr = ", SDr

Mg = np.mean(Ag)
SDg = np.std(Ag)
Thg = np.mean(Ag) + 2 * np.std(Ag) + 50 + 12

Thr = 50 - 12 - np.std(Ar)
print "Thr = ", Thr
Dd = np.zeros((height, width))
Dc = Dd
for i in range(height):
    for j in range(width):

        if Ar[i][j] > Thr:
            Dd[i][j] = 255
        else:
            Dd[i][j] = 0

TDd = np.uint8(Dd)
TDd2 = Dd

for i in range(height):
    for j in range(width):
        if Ag[i][j] > Thg:
            Dc[i][j] = 1
        else:
            Dc[i][j] = 0

#CALCULATING RATIO
ratio = 500.0 / Dd.shape[1]
dim = (500, int(Dd.shape[0] * ratio))
#
# #RESIZING TO-BE-DISPLAYED IMAGES
resized_TDd = cv2.resize(TDd, dim, interpolation=cv2.INTER_AREA)
resized_TDd2 = cv2.resize(TDd2, dim, interpolation=cv2.INTER_AREA)
resized_original = cv2.resize(Aro, dim, interpolation=cv2.INTER_AREA)

cv2.imshow('TDd', resized_TDd)
cv2.imshow('TDd2', resized_TDd2)
cv2.imshow('Aro', resized_original)
cv2.waitKey(0)

Ar[][] has -ve as well as +ve values and Thr has a -ve value. Dd is the image which i want to display. The problem is that TDd displays a bizarre image (255s and 0s are being assigned to appropriate pixels, i checked but the image being displayed is weird and not similar to TDd

Original image

enter image description here

Red channel image:

enter image description here

TDd (uint8 of Dd):

enter image description here

TDd2 (same as Dd)

enter image description here

Dd2 (declared uint8 dtype while initializing)

enter image description here

Why are the TDd and TDd2 images different? Since the difference between the gray values of the pixels (as far as i understand and know) in these 2 images is only 255, 0 (in TDd) and 255.0, 0.0 (in TDd2).

It would be a great great help if someone could tell me.

2

2 Answers

1
votes

Usually when Images are represented with np float64 arrays, RGB values are in range 0 to 1. So when converting to uint8 there is a possible precision loss when converting from float64 to uint8.

I would directly create Dd as a:

Dd = np.zeros((height, width), dtype=np.uint8)

Then it should work.

1
votes

Look I executed your code and there are the results

They seem pretty normal to me... this is the exact code I used

Ar is different from the others because when you imShow() it, it puts white where values are > 0 black otherwise. The other matrices after tour code get white where > Thr which is less than 0, so more pixel get white obviously.

update

You assigned Dd to Dc when you should've done Dc = np.zeros((height, width)).