简体   繁体   中英

How to normalize a tiff image

I am trying to set some specific pixels inside a image to black, those images are in tiff format, which requires me to decompose them in their respective frames, therefore my tiff image has 50 different frames. For such task, I am using simple values by accessing the pixel index at their given position and simply setting their values to 0. For instance:

img[10, 50] = 0

every time I try setting their pixels the image goes yellow instantly.

在此处输入图像描述

However, if I remove every line that changes/sets the pixel values to black, the image goes back to normal.

Here's my code:

from PIL import Image
%pylab inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg


image = "myimage.tif"
path = "C:/Dataset/Face1" + image

 plt.imshow(img)
img=mpimg.imread(path)
img[15, 60] = 0
img[15, 85] = 0
img[15, 105] = 0
img[35, 60] = 0
img[35, 85] = 0
img[35, 105] = 0
img[45, 60] = 0
img[43, 75] = 0
img[43, 92] = 0
img[43, 105] = 0
img[58, 55] = 0
img[65, 83] = 0
img[58, 110] = 0
img[75, 83] = 0
img[85, 75] = 0
img[85, 90] = 0
img[90 ,83] = 0
img[95, 60] = 0
img[99, 83] = 0
img[99, 103] = 0

I tried normalizing my image the easy way using opencv2:

img1 = cv2.imread('image.tif', cv2.IMREAD_GRAYSCALE)
final_img = cv2.normalize(img1,  img1, 0, 255, cv2.NORM_MINMAX)

Got this instead:

在此处输入图像描述

How i am decomposing the images

from PIL import Image
import matplotlib.pyplot as plt
imagepath = "face1.tif"
path = "C:/Users/images/" + imagepath
img = Image.open(path)

for i in range(50):
    try:
        img.seek(i)
        img.save('C:/Users/images/face1/%s.tif'%(i,))
    except EOFError:
        break

What i want to do is normalize the image, when i print the values of one of the lightest pixel, the output is something around 8353. Also, convert it to 8bit image, so i can view it on matplotlib.

You can do proper normalization using Scipy exposure.rescale_intensity() with Python/OpenCV.

In the following, I use OpenCV to read the multi-page TIFF and process the frames in a loop as follows:

import cv2
import numpy as np
import skimage.exposure as exposure

# read images
imgs = cv2.imreadmulti("face_1.tif", flags = cv2.IMREAD_GRAYSCALE + cv2.IMREAD_ANYDEPTH)[1]

for i,img in enumerate(imgs):
    filename = f"face_1_frame-{i}.png"
    print(f"Processing frame {i} into file {filename}")
    # normalize image to 8-bit range
    img_norm = exposure.rescale_intensity(img, in_range='image', out_range=(0,255)).astype(np.uint8)
    cv2.imwrite(filename, img_norm)

    # display normalized image
    cv2.imshow('normalized',img_norm)
    cv2.waitKey(0)

Here is the first normalized frame:

在此处输入图像描述

Most probably your images use some non-standard encoding scheme. Normally, the pixel values (for a single channel) are bounded to [0..255]. In your case pixel values lie in the range [8162..8383]. matplotlib normalizes that range for you automatically. But when you set one of the pixel values to 0, your range becomes [0..8383] and this is the reason why it struggles to display it. Just normalize the data:

from matplotlib import pyplot as plt
img = plt.imread(r'C:\temp\face_1.tif')
img -= img.min() # you can use more sofisticated img = 255*(img - img.min())/(img.max() - img.min())
img[90 ,83] = 0
img[95, 60] = 0
img[99, 83] = 0
img[99, 103] = 0
plt.imshow(img, cmap='gray')
plt.show()

And this will get you: 在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM