Python error : index out of bounds - python

I was curious about image processing with python, so I found this great library imageio,
I tried to manipulate the pixels of a picture and save them in a new file,
but i had some problems with the loops
this is what the code looks like
enter image description here
and this the error that i Got !
IndexError: index 3507 is out of bounds for axis 0 with size 3507
the code :
# -*- coding: iso-8859-1 -*-
import imageio
import numpy as np
im = imageio.imread("JAFFRE009a.png")
taille=im.shape #taille is a tuple (Width,Height)
print taille # (4961,3507)
matrice_pixels=open("matrice.txt",'w')
for i in range(taille[1]):
line=""
for j in range(taille[0]):
line+=repr(im[i][j])
matrice_pixels.write(line+'\n')
matrice_pixels.close()

Because your image doesn't have squarred shape, reshape it before you go through your loop

EDIT
We can iterate through each row/column position and save to a file as below.It will take very long time depending upon file size.
Instead of writing your own function, you may want to take advantage of inbuilt binary save (which is more efficient) as
np.save('matrix.py', np_array)
You can load this file as np array and manipulate
Or as a text file using np.save [ will take longer ]
np.save('matrix.txt', np_array)
Working Code:
import imageio
import numpy as np
im = imageio.imread("9v9zU.png")
matrice_pixels=open("matric.txt","wb")
nx,ny = im.shape
for i in range(nx):
line=""
for j in range(ny):
line+=repr(im[i][j])
matrice_pixels.write(line+'\n')
matrice_pixels.close()
#Save as Binary data
np.save('matrix1.npy', im)
#Save as Human readable data
np.savetxt('matrix1.txt', im)
Alternately, you may want to look into off the shelf libraries that will do what you are intending to do.
For e.g. This SO link discusses how to remove section of the picture based upon its color using PIL library.
Also , in future, please DO NOT post a picture of your code. Copy/pase to SO window so that we can copy and modify. In this case I had write everything down line by line to test(thankfully code was not that long).

Related

How do I create image from binary data BSQ?

I've got a problem. I'm trying create image from binary data which I got from hyperspectral camera. The file which I have is in BSQ uint16 format. From the documentation I found out that images contained in the file (.dat) have a resolution of 1024x1024 and there are 24 images in total. The whole thing is to form a kind of "cube" which I want use in the future to creat multi-layered orthomosaic.
I would also like to add that I am completely new in python but I try to be up to date with everything I need. I hope that everything what I have written is clear and uderstandable.
At first I tried to use Numpy liblary to creating 3D array but ended up with an arrangement of random pixels.
from PIL import Image
import numpy as np
file=open('Sequence 1_000021.dat','rb')
myarray=np.fromfile(file,dtype=np.uint16)
print('Size of new array',":", len(myarray))
con_array=np.reshape(myarray,(24,1024,1024),'C')
naPIL=Image.fromarray(con_array[1,:,:])
naPIL.save('naPIL.tiff')
The result: enter image description here
Example of image which I want to achieve (thumbnail): enter image description here
As suspected it's just byte order, I get a sensible looking image when running the following code in a Jupyter notebook:
import numpy as np
from PIL import Image
# open as big-endian, convert to native order, then reshape as appropriate
raw = np.fromfile(
'./Sequence 1_000021.dat', dtype='>u2'
).astype('uint16').reshape((24, 1024, 1024))
# display inline
Image.fromarray(raw[1,:,:])

convert .nii to .tif using imwrite, it saves black image insted of the image

I want to convert .nii images to .tif to train my model using U-Net.
1-I looped through all images in the folder.
2-I looped through all slices within each image.
3-I saved each slice as .tif.
The training images are converted successfully. However, the labels (masks) are all saved as black images. I want to successfully convert those masks from .nii to .tif, but I don't know how. I read that it could be something with brightness, but I didn't get the idea clearly, so I couldn't solve the problem until now.
The only reason for this conversion is to be able to train my model. Feel free to suggest a better idea, if anyone can share a way to feed the network with the .nii format directly.
import nibabel as nib
import matplotlib.pyplot as plt
import imageio
import numpy as np
import glob
import os
import nibabel as nib
import numpy as np
from tifffile import imsave
import tifffile as tiff
for filepath in glob.iglob('data/Task04_Hippocampus/labelsTr/*.nii.gz'):
a = nib.load(filepath).get_fdata()
a = a.astype('int8')
base = Path(filepath).stem
base = re.sub('.nii', '', base)
x,y,z = a.shape
for i in range(0,z):
newimage = a[:, :, i]
imageio.imwrite('data/Task04_Hippocampus/masks/'+base+'_'+str(i)+'.tif', newimage)
Unless you absolutely have to use TIFF, I would strongly suggest using the NiFTI format for a number of important reasons:
Image values are often not arbitrary. For example, in CT images the values correspond to x-ray attenuation (check out this Wikipedia page). TIFF, which is likely to scale the values in some way, is not suitable for this.
NIfTI also contains a header which has crucial geometric information needed to correctly interpret the image, such as the resolution, slice thickness, and direction.
You can directly extract a numpy.ndarray from NIfTI images using SimpleITK. Here is a code snippet:
import SimpleITK as sitk
import numpy as np
img = sitk.ReadImage("your_image.nii")
arr = sitk.GetArrayFromImage(img)
slice_0 = arr[0,:,:] # this is a 2D axial slice as a np.ndarray
As an aside: the reason the images where you stored your masks look black is because in NIfTI format labels have a value of 1 (and background is 0). If you directly convert to TIFF, a value of 1 is very close to black when interpreted as an RGB value - another reason to avoid TIFF!

Python: SVG to PNG converting issue

UPDATE: I tried increasing size in the chess.svg.board and it somehow cleared all the rendering issues at size = 900 1800
I tried using the svglib and reportlab to make .png files from .svg, and here is how the code looks:
import sys
import chess.svg
import chess
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM
board = chess.Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")
drawing = chess.svg.board(board, size=350)
f = open('file.svg', 'w')
f.write(drawing)
drawing = svg2rlg("file.svg")
renderPM.drawToFile(drawing, "file.png", fmt="png")
If you try to open file.png there is a lot of missing parts of the image, which i guess are rendering issues. How can you fix this?
Sidenote: also getting a lot of 'x_order_2: colinear!' messages when running this on a discord bot, but I am not sure if this affects anything yet.
THIS!! I am having the same error with the same libraries... I didn't find a solution but just a workaround which probably won't help too much in your case, where the shapes generating the bands are not very sparse vertically.
I'll try playing with the file dimensions too, but so far this is what I got. Note that my svg consists of black shapes on a white background (hence the 255 - x in the following code)
Since the appearance of the bands is extremely random, and processing the same file several times in a row produces different results, I decided to take advantage of randomness: what I do is I export the same svg a few times into different pngs, import them all into a list and then only take those pixels that are white in all the exported images, something like:
images_files = [my_convert_function(svgfile=file, index=i) for i in range(3)]
images = [255 - imageio.imread(x) for x in images_files]
result = reduce(lambda a,b: a & b, images)
imageio.imwrite(<your filename here>, result)
[os.remove(x) for x in images_files]
where my_convert_function contains your same svg2rlg and renderPM.drawToFile, and returns the name of the png file being written. The index 'i' is to save several copies of the same png with different names.
It's some very crude code but I hope it can help other people with the same issue
The format parameter has to be in uppercase
renderPM.drawToFile(drawing, "file.png", fmt="PNG")

Writing seemingly same array to two image files leads to different results

I'm trying to read and write tiff-images with the PIL library. While testing, I noticed that saving the seemingly same numpy array generated in different ways leads to different images on disk. Why is this and how can I fix it?
For testing purposes, I created an image with GIMP (upscaled from 8x8) which I saved as TIF, read to a numpy array and wrote back to a tif file:
img_gimp = Image.open('img_gimp.tif')
imgarray_gimp = np.array(img_gimp)
img_gimp = Image.fromarray(imgarray_gimp, mode = 'I;16')
img_gimp.save('final_gimp.tif')
The result is as expected, it is the same image as the original. So far so good.
Now I generated the same image directly in python code:
imgarray_direct = np.zeros(shape = (8, 8)).astype(int)
for i in range(2):
for j in range(2):
image[i][j] = 65535
Writing this array to disk...
img_direct = Image.fromarray(imgarray_direct, mode = 'I;16')
img_direct.save('final_direct.tif')
doesn't give me the expected result, instead I find this:
image generated by for loop (upscaled from 8x8)
Doing
print(np.array_equal(imgarray_gimp, imgarray_direct))
gives True, and looking at print(imgarray_gimp) and print(imgarray_direct), one cannot see any difference.
Is this intended behaviour? If yes, whats the reason for it?
Thank you for your answers!
As #MarkSetchell hinted in the comments, the issue is that your dtype for the numpy array of raw data does not match the PIL image mode string you are supplying afterwards. Changing the parameter passed into astype or simply passing in the right type on array creation fixed this issue for me. Here is what the modified code looks like:
import numpy as np
from PIL import Image
#Generate raw image data (16-bit!)
image_data = np.zeros(shape = (8, 8), dtype=np.uint16)#this is the big change
for i in range(2):
for j in range(2):
image_data[i][j] = 65535
#Save image as TIF to disk
image_direct = Image.fromarray(image_data, mode = 'I;16')
image_direct.save('final_direct.tif')
As a side note, I am surprised that the mode string I;16 you have used is valid; I could not find any mention about it in pillow's documentation.

How to create a .png file using python?

I am trying to create a .png file from uint8array but am not getting the expected result. The file is 908 bytes but it is supposed to be of 905 bytes. When I try to open the image in the MS paint, it says This is not a valid bitmap file. The same array works for me when I use node.js. Here is the code :
import io
import numpy as np
arr =[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,200,0,0,0,200,8,6,0,0,0,173,88,174,158,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,3,43,73,68,65,84,120,156,237,221,193,110,163,48,20,64,209,206,168,255,255,203,51,251,44,174,21,192,177,33,231,236,41,52,237,149,37,30,14,63,63,0,0,0,0,0,0,0,0,0,0,19,253,57,120,220,191,75,175,98,236,232,117,114,15,219,254,63,253,157,121,21,112,119,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,191,147,126,174,185,5,239,184,250,255,229,178,185,138,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,172,103,177,222,245,233,61,201,239,58,251,172,208,236,223,111,247,235,59,107,217,179,125,86,16,8,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,71,231,32,159,190,47,61,251,124,103,231,0,163,227,103,207,41,102,159,127,247,207,255,213,101,215,107,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,126,144,179,102,207,1,70,86,239,199,88,253,93,200,171,63,255,105,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,158,50,7,89,125,159,253,238,251,49,206,218,253,250,14,179,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,184,203,28,228,238,239,175,56,59,39,89,189,223,98,247,207,127,26,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,199,62,199,255,97,171,223,15,226,239,56,137,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,183,236,7,121,250,126,139,213,251,77,86,127,126,211,88,65,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,236,50,7,217,125,63,197,234,227,207,90,125,254,145,109,175,207,10,2,65,32,16,4,2,65,32,16,4,2,65,32,16,4,2,97,245,253,239,171,124,251,156,98,245,241,35,179,247,243,76,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,246,125,252,145,217,63,223,249,207,157,127,25,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,109,239,63,191,184,251,126,135,167,255,252,213,199,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,151,57,200,200,234,253,32,171,143,31,121,202,223,249,227,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,238,242,158,244,145,213,239,175,152,109,245,251,73,86,179,31,4,118,36,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,228,233,251,37,118,127,255,198,215,206,97,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,118,153,131,220,253,62,253,232,252,187,127,111,214,89,219,190,223,227,44,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,93,230,32,171,239,227,143,172,126,15,249,200,234,57,195,234,243,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,116,14,242,233,231,255,87,239,167,120,250,123,216,71,118,159,83,189,186,236,243,176,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,56,122,127,252,177,223,131,196,35,152,131,192,39,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,204,250,110,222,171,247,48,123,182,235,217,182,221,243,110,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,1,0,0,0,0,0,0,0,0,56,239,63,169,44,80,125,75,214,2,231,0,0,0,0,73,69,78,68,174,66,96,130]
arr = np.array(arr, dtype=np.uint8)
np.set_printoptions(formatter={'int':hex})
arr=np.array(arr)
f=open("QR icon.png","w")
f.write(arr)
f.close()
Also when I open the created image in notepad, there is an extra space which is not there in the file I created using node. I think I am creating the file in a wrong way. Please help me .....
Okay, first your code didn't work for me i run into a few small errors. When i fixed them, it solved you initial problem:
import io
import numpy as np
arr =[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,200,0,0,0,200,8,6,0,0,0,173,88,174,158,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,3,43,73,68,65,84,120,156,237,221,193,110,163,48,20,64,209,206,168,255,255,203,51,251,44,174,21,192,177,33,231,236,41,52,237,149,37,30,14,63,63,0,0,0,0,0,0,0,0,0,0,19,253,57,120,220,191,75,175,98,236,232,117,114,15,219,254,63,253,157,121,21,112,119,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,191,147,126,174,185,5,239,184,250,255,229,178,185,138,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,172,103,177,222,245,233,61,201,239,58,251,172,208,236,223,111,247,235,59,107,217,179,125,86,16,8,2,129,32,16,8,2,129,32,16,8,2,129,32,16,8,71,231,32,159,190,47,61,251,124,103,231,0,163,227,103,207,41,102,159,127,247,207,255,213,101,215,107,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,126,144,179,102,207,1,70,86,239,199,88,253,93,200,171,63,255,105,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,158,50,7,89,125,159,253,238,251,49,206,218,253,250,14,179,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,184,203,28,228,238,239,175,56,59,39,89,189,223,98,247,207,127,26,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,199,62,199,255,97,171,223,15,226,239,56,137,21,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,194,183,236,7,121,250,126,139,213,251,77,86,127,126,211,88,65,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,236,50,7,217,125,63,197,234,227,207,90,125,254,145,109,175,207,10,2,65,32,16,4,2,65,32,16,4,2,65,32,16,4,2,97,245,253,239,171,124,251,156,98,245,241,35,179,247,243,76,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,246,125,252,145,217,63,223,249,207,157,127,25,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,109,239,63,191,184,251,126,135,167,255,252,213,199,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,151,57,200,200,234,253,32,171,143,31,121,202,223,249,227,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,238,242,158,244,145,213,239,175,152,109,245,251,73,86,179,31,4,118,36,16,8,2,129,32,16,8,2,129,32,16,8,2,129,176,203,28,100,228,233,251,37,118,127,255,198,215,206,97,172,32,16,4,2,65,32,16,4,2,65,32,16,4,2,65,32,16,118,153,131,220,253,62,253,232,252,187,127,111,214,89,219,190,223,227,44,43,8,4,129,64,16,8,4,129,64,16,8,4,129,64,16,8,132,93,230,32,171,239,227,143,172,126,15,249,200,234,57,195,234,243,79,99,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,129,112,116,14,242,233,231,255,87,239,167,120,250,123,216,71,118,159,83,189,186,236,243,176,130,64,16,8,4,129,64,16,8,4,129,64,16,8,4,129,64,56,122,127,252,177,223,131,196,35,152,131,192,39,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,8,4,130,64,32,204,250,110,222,171,247,48,123,182,235,217,182,221,243,110,5,129,32,16,8,2,129,32,16,8,2,129,32,16,8,2,1,0,0,0,0,0,0,0,0,56,239,63,169,44,80,125,75,214,2,231,0,0,0,0,73,69,78,68,174,66,96,130]
arr = np.array(arr, dtype=np.uint8)
np.set_printoptions(formatter={'int':hex})
arr=np.array(arr)
f=open("QR icon.png","wb")
f.write(arr.tostring())
f.close()
The difference is the wb so that i can write binary and the arr.tostring(). When i checked the properties it had the 905 pixels.

Categories