Python array to Image, over 255 - python

I want to save array that array's element is over 255 to image file (.jp2). Data type is 'int32'. Is there any method to save array to image that array's element is over 255? This is used for processing sentinel-2 datasets.
I already tried it with cv2, pil, scipy functions.
but it doesn't work.
-
imwrite, scipy.misc.toimage, scipy.misc.imsave, .save()...
I already tried these functions..
For example, h_01 array is like this.
[[1419. 1448.5 1444. ... 1388.5 1390.5 1391.5]
[1449.5 1434. 1448. ... 1370. 1372. 1373. ]
[1424.5 1428.5 1457. ... 1353.5 1354.5 1378. ]
...
[1430. 1412.5 1422.5 ... 1500. 1474.5 1495. ]
[1449.5 1409.5 1417.5 ... 1472.5 1492. 1512.5]
[1447.5 1429. 1437. ... 1492. 1511.5 1509.5]]
and I changed my data to int32.
h_01=np.array(h_01,np.int32)
then, I save this array to image
scipy.misc.toimage(h_01).save(opt.image+"_01.jp2")
in this method, array saved like this.
[[28 33 32 ... 23 23 23]
[33 31 33 ... 20 20 20]
[29 30 34 ... 17 17 21]
...
[30 27 28 ... 42 37 41]
[33 26 28 ... 37 40 44]
[33 30 31 ... 40 44 43]]
I want to save array that element is over 255 to image file(.jp2).
but it doesn't work, results that saved are not over 255 (have loss).

Related

Normalization problem when running my image processing

I am trying to normalize the images and used the following code to do that but when trying to normalize
img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX)
when I print the image using print(img)
i get the following as if No normalization was applied to the image
[[199 204 205 ... 29 30 34]
[195 200 203 ... 30 30 32]
[190 195 200 ... 35 31 29]
...
[ 7 3 1 ... 16 16 15]
[ 19 13 7 ... 18 18 17]
[ 35 26 19 ... 18 20 19]]
I tried to use another approach as
img/255 or img/255.0.
I still can see black images and upon printing print(img) I get the following as:
[[0.78039216 0.8 0.80392157 ... 0.11372549 0.11764706 0.13333333]
[0.76470588 0.78431373 0.79607843 ... 0.11764706 0.11764706 0.1254902 ]
[0.74509804 0.76470588 0.78431373 ... 0.1372549 0.12156863 0.11372549]
I am kind of confused on why I get the black images ?
...
You probably have very small areas with luminosity that is very close to 255. That will "halt" the normalization.
What you can do is use some kind of thresholding to remove, say, all intensities from 220 to 255 and map them to 220. If you normalize that, the points with intensity 220 will be driven up to 255, but this time the darker values will get amplified too.
However, I think you're likely to get better answers if you describe in more detail what you're trying to accomplish - what the image is, and to what end you want to normalize it.

How do I sort columns of numerical file data in python

I'm trying to write a piece of code in python to graph some data from a tab separated file with numerical data.
I'm very new to Python so I would appreciate it if any help could be dumbed down a little bit.
Basically, I have this file and I would like to take two columns from it, sort them each in ascending order, and then graph those sorted columns against each other.
First of all, you should not put code as images, since there is a functionality to insert and format here in the editor.
It's as simple as calling x.sort() and y.sort() since both of them are slices from data so that should work fine (assuming they are 1 dimensional arrays).
Here is an example:
import numpy as np
array = np.random.randint(0,100, size=50)
print(array)
Output:
[89 47 4 10 29 21 91 95 32 12 97 66 59 70 20 20 36 79 23 4]
So if we use the method mentioned before:
print(array.sort())
Output:
[ 4 4 10 12 20 20 21 23 29 32 36 47 59 66 70 79 89 91 95 97]
Easy as that :)

Cannot retrieve Original image from Encrypted image In Python using PIL

I am writing a script that can encrypt and decrypt an image using the RSA algorithm. My public key is (7, 187) and the private key is (23,187) now the calculation for the encryption is correct like for an entry in the matrix of the image, 41 the encrypted value is 46. But when the decryption is happening it is not giving the appropriate result like for 46 it is giving 136 and for every entry of 46 in the encrypt matrix the result I am getting is 136 in the decrypt matrix. And I don't know why this is happening. When I am doing the same calculation in the python prompt(or shell) it is giving the correct answer.
In the script, I am first converting the RGB image into grayscale and then converting it to a 2d numpy array, then for each element, I am applying the RSA algo(the keys) and then saving it as an image. Then I am applying the decryption key in the encrypted matrix and then the problem is occurring. Heres the code:
from PIL import Image
import numpy as np
from pylab import *
#encryption
img1 = (Image.open('image.jpeg').convert('L'))
img1.show()
img = array((Image.open('image.jpeg').convert('L')))
a,b = img.shape #saving the no of rows and col in a tuple
print('\n\nOriginal image: ')
print(img)
print((a,b))
tup = a,b
for i in range (0, tup[0]):
for j in range (0, tup[1]):
img[i][j]= (pow(img[i][j],7)%187)
print('\n\nEncrypted image: ')
print(img)
imgOut = Image.fromarray(img)
imgOut.show()
imgOut.save('img.bmp')
#decryption
img2 = (Image.open('img.bmp'))
img2.show()
img3 = array(Image.open('img.bmp'))
print('\n\nEncrypted image: ')
print(img3)
a1,b1 = img3.shape
print((a1,b1))
tup1 = a1,b1
for i1 in range (0, tup1[0]):
for j1 in range (0, tup1[1]):
img3[i1][j1]= ((pow(img3[i1][j1], 23))%187)
print('\n\nDecrypted image: ')
print(img3)
imgOut1 = Image.fromarray(img3)
imgOut1.show()
print(type(img))
The values of the matrices:
Original image:
[[41 42 45 ... 47 41 33]
[41 43 45 ... 44 38 30]
[41 42 46 ... 41 36 30]
...
[43 43 44 ... 56 56 55]
[45 44 45 ... 55 55 54]
[46 46 46 ... 53 54 54]]
Encrypted image:
[[ 46 15 122 ... 174 46 33]
[ 46 87 122 ... 22 47 123]
[ 46 15 7 ... 46 9 123]
...
[ 87 87 22 ... 78 78 132]
[122 22 122 ... 132 132 164]
[ 7 7 7 ... 26 164 164]]
Decrypted image:
[[136 70 24 ... 178 136 164]
[136 111 24 ... 146 141 88]
[136 70 96 ... 136 100 88]
...
[111 111 146 ... 140 140 1]
[ 24 146 24 ... 1 1 81]
[ 96 96 96 ... 52 81 81]]
Any help will be greatly appreciated. Thank You.
I think you will get on better using the 3rd parameter to the pow() function which does the modulus internally for you.
Here is a little example without the complexity of loading images - just imagine it is a greyscale gradient from black to white.
# Make single row greyscale gradient from 0..255
img = [ x for x in range(256) ]
# Create encrypted version
enc = [ pow(x,7,187) for x in img ]
# Decrypt back to plaintext
dec = [ pow(x,23,187) for x in enc ]
It seems to decrypt back into the original values from 0..187, where it goes wrong - presumably because of overflow? Maybe someone cleverer than me will be able to explain that - please add comment for me if you know!

Argument must be a string, a bytes-like object or a number, not 'slice'

I am having troubles with deleting slices from a numpy array.
x_train[:,:,0]
returns the data I want to delete
but
np.delete(x_train, np.s_[:,:,0])
throws the exception
TypeError: int() argument must be a string, a bytes-like object or a number, not 'slice'
But in the documentation it is written
Return a new array with sub-arrays along an axis deleted. For a one dimensional array, this returns those entries not returned by arr[obj].
obj : slice, int or array of ints
Indicate which sub-arrays to remove.
First, in this case, np.s_ return a tuple, not a slice.
In the documentation, they say you can pass a slice as argument, but in fact they mean the python built in slice class (Doc)
A valid code would be:
x = [[[1,2,3],[4,5,6]],[[1,1,1],[2,2,2]],[[5,5,5],[7,7,7]]]
np.delete(x, slice(1,1,1))
But let's take a look at the output of np.s_.
print(np.s_[:,:,0])
returns
(slice(None,None,None), slice(None,None,None), 0)
The output of np.s_ is a tuple of objets, some are slices and some are indexes, you should read the doc of np.s_ for more information to know how to use it.
In fact the slice is the object that allow you to write mylist[0:3], in fact this code is just mylist[slice(0,3)]
mylist[:], is a special case of slice, in fact : is a slice from 0 to len(mylist)-1.
You can try this:
arr1 = np.delete(arr1, 0, axis=-1)
Testing it out:
import numpy as np
arr1 = np.arange(48).reshape(2,3,8)
print (arr1)
arr1 = np.delete(arr1, 0, axis=-1)
print (arr1)
Output:
# Before delete
[[[ 0 1 2 3 4 5 6 7]
[ 8 9 10 11 12 13 14 15]
[16 17 18 19 20 21 22 23]]
[[24 25 26 27 28 29 30 31]
[32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47]]]
# After delete
[[[ 1 2 3 4 5 6 7]
[ 9 10 11 12 13 14 15]
[17 18 19 20 21 22 23]]
[[25 26 27 28 29 30 31]
[33 34 35 36 37 38 39]
[41 42 43 44 45 46 47]]]
I think the problem is in your slice which is not working there. Try
np.delete(x_train, np.s_[1,1,1])

Remove Specific Indices From 2D Numpy Array

If I have a set of data that's of shape (1000,1000) and I know that the values I need from it are contained within the indices (25:888,11:957), how would I go about separating the two sections of data from one another?
I couldn't figure out how to get np.delete() to like the specific 2D case and I also need both the good and the bad sections of data for analysis, so I can't just specify my array bounds to be within the good indices.
I feel like there's a simple solution I'm missing here.
Is this how you want to divide the array?
In [364]: arr = np.ones((1000,1000),int)
In [365]: beta = arr[25:888, 11:957]
In [366]: beta.shape
Out[366]: (863, 946)
In [367]: arr[:25,:].shape
Out[367]: (25, 1000)
In [368]: arr[888:,:].shape
Out[368]: (112, 1000)
In [369]: arr[25:888,:11].shape
Out[369]: (863, 11)
In [370]: arr[25:888,957:].shape
Out[370]: (863, 43)
I'm imaging a square with a rectangle cut out of the middle. It's easy to specify that rectangle, but the frame is has to be viewed as 4 rectangles - unless it is described via the mask of what is missing.
Checking that I got everything:
In [376]: x = np.array([_366,_367,_368,_369,_370])
In [377]: np.multiply.reduce(x, axis=1).sum()
Out[377]: 1000000
Let's say your original numpy array is my_arr
Extracting the "Good" Section:
This is easy because the good section has a rectangular shape.
good_arr = my_arr[25:888, 11:957]
Extracting the "Bad" Section:
The "bad" section doesn't have a rectangular shape. Rather, it has the shape of a rectangle with a rectangular hole cut out of it.
So, you can't really store the "bad" section alone, in any array-like structure, unless you're ok with wasting some extra space to deal with the cut out portion.
What are your options for the "Bad" Section?
Option 1:
Be happy and content with having extracted the good section. Let the bad section remain as part of the original my_arr. While iterating trough my_arr, you can always discriminate between good and and bad items based on the indices. The disadvantage is that, whenever you want to process only the bad items, you have to do it through a nested double loop, rather than use some vectorized features of numpy.
Option 2:
Suppose we want to perform some operations such as row-wise totals or column-wise totals on only the bad items of my_arr, and suppose you don't want the overhead of the nested for loops. You can create something called a numpy masked array. With a masked array, you can perform most of your usual numpy operations, and numpy will automatically exclude masked out items from the calculations. Note that internally, there will be some memory wastage involved, just to store an item as "masked"
The code below illustrates how you can create a masked array called masked_arr from your original array my_arr:
import numpy as np
my_size = 10 # In your case, 1000
r_1, r_2 = 2, 8 # In your case, r_1 = 25, r_2 = 889 (which is 888+1)
c_1, c_2 = 3, 5 # In your case, c_1 = 11, c_2 = 958 (which is 957+1)
# Using nested list comprehension, build a boolean mask as a list of lists, of shape (my_size, my_size).
# The mask will have False everywhere, except in the sub-region [r_1:r_2, c_1:c_2], which will have True.
mask_list = [[True if ((r in range(r_1, r_2)) and (c in range(c_1, c_2))) else False
for c in range(my_size)] for r in range(my_size)]
# Your original, complete 2d array. Let's just fill it with some "toy data"
my_arr = np.arange((my_size * my_size)).reshape(my_size, my_size)
print (my_arr)
masked_arr = np.ma.masked_where(mask_list, my_arr)
print ("masked_arr is:\n", masked_arr, ", and its shape is:", masked_arr.shape)
The output of the above is:
[[ 0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]]
masked_arr is:
[[0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 -- -- 25 26 27 28 29]
[30 31 32 -- -- 35 36 37 38 39]
[40 41 42 -- -- 45 46 47 48 49]
[50 51 52 -- -- 55 56 57 58 59]
[60 61 62 -- -- 65 66 67 68 69]
[70 71 72 -- -- 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]] , and its shape is: (10, 10)
Now that you have a masked array, you will be able to perform most of the numpy operations on it, and numpy will automatically exclude the masked items (the ones that appear as "--" when you print the masked array)
Some examples of what you can do with the masked array:
# Now, you can print column-wise totals, of only the bad items.
print (masked_arr.sum(axis=0))
# Or row-wise totals, for that matter.
print (masked_arr.sum(axis=1))
The output of the above is:
[450 460 470 192 196 500 510 520 530 540]
[45 145 198 278 358 438 518 598 845 945]

Categories