How to invert axis of a pillow image - python

Seaborn offers the possibility to invert the axis of an image. I would like to do the same with PIL. Here is my code.
# Imports
import seaborn as sns; sns.set_theme()
import matplotlib.pyplot as plt
import numpy as np
import numpy as np; np.random.seed(0)
from PIL import Image
import random
# Arrays
r = []
g = []
b = []
for i in range(200):
r.append(random.sample(range(0, 255), 200))
g.append(random.sample(range(0, 255), 200))
b.append(random.sample(range(0, 255), 200))
# Change color of the left part of the image
r = np.array(r)
r[:, 0:10]=0
# Change color of the right part of the image
r = np.array(r)
r[:, -10:-1]=150
g = np.array(g)
g[:, -10:-1]=150
# Plot seaborn heatmap
fig, ax = plt.subplots()
sax = sns.heatmap(r)
sax.invert_xaxis()
sax.invert_xaxis() inverts the x-axis of the plot.
I would like to do the same with pillow. I have been google it for a long time without finding anything.
Here is my rgb pillow image.
rgbarr = np.zeros((200,200,3), 'uint8')
rgbarr[..., 0] = np.array(r)
rgbarr[..., 1] = np.array(g)
rgbarr[..., 2] = np.array(b)
img = Image.fromarray(rgbarr)
img
opencv possibility would also be welcome.

I think you just want to flip it:
im_flipped = im.transpose(method=Image.FLIP_LEFT_RIGHT)

Related

How to make colormaps for this image in python m?

I want to make a colormap used in the attached image colorbar. I could do it MATLAB, however, I can't seem to do it in python. So far I tried the code given below but didn't get the result I was looking for.
img = imread('/path/colorbarimage.png')
colors_from_img = img[:, 0, :]
my_cmap = LinearSegmentedColormap.from_list('my_cmap', colors_from_img, N=651)
y = random_sample((100, 100))
imshow(y, cmap=my_cmap);plt.colorbar()
With img[:, 0, :] you're not picking the correct column in the colorbar image (if indeed colorbarimage.png is the image you linked).
The following works fine:
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
img = plt.imread('colorbarimage.png')
# to check the selected rectangle:
cropped_cmap = img[145:799, 70:80, :]
plt.imshow(cropped_cmap)
plt.show()
colors_from_img = img[145:799, 74, :]
my_cmap = LinearSegmentedColormap.from_list('my_cmap', colors_from_img, N=256)
y = np.random.random_sample((100, 100))
plt.imshow(y, cmap=my_cmap)
plt.colorbar()
plt.show()

Performing a polar transformation on an image in reverse clock direction using scikit-image

As the following experiment shows, the warp_polar function of the scikit-image library performs the polar transformation in clock direction. However, I want to perform a polar transformation in the reverse clock direction. I should probably flip or rotate the image in some way to achieve the desired end result. However, I am not sure how to do this. I would appreciate any efficient solution.
In a correct solution, the transformed image would have the following sequence of numbers: 3, 2, 1, 12, 11, 10....
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import matplotlib.gridspec as gridspec
from skimage.transform import warp_polar
import cv2
testImg = cv2.cvtColor(mpimg.imread('clock.png'), cv2.COLOR_BGR2GRAY)
pol = warp_polar(testImg, radius=min(testImg.shape)/2)
# Create 2x2 sub plots
gs = gridspec.GridSpec(1, 2)
fig = plt.figure()
ax1 = fig.add_subplot(gs[0, 0]) # row 0, col 0
ax1.imshow(testImg)
ax1.set_title("Original Image")
ax2 = fig.add_subplot(gs[0, 1]) # row 0, col 1
ax2.imshow(pol)
ax2.set_title("Polar Transformation")
plt.show()
Thanks to the comment, I found out that the solution was much simpler than I thought. Flipping the result of warp_polar vertically is equivalent to applying the polar transformation in the reverse clock direction.
import numpy as np
pol = np.flip(pol,0)
you could flip the image on axis prior to input, then run your current polar warp to get the result like this:
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import matplotlib.gridspec as gridspec
from skimage.transform import warp_polar
import cv2
testImg = cv2.cvtColor(mpimg.imread('clock.png'), cv2.COLOR_BGR2GRAY)
horizontal_flip = testImg[:, ::-1]
pol = warp_polar(horizontal_flip, radius=min(horizontal_flip.shape)/2)
# Create 2x2 sub plots
gs = gridspec.GridSpec(1, 2)
fig = plt.figure()
ax1 = fig.add_subplot(gs[0, 0]) # row 0, col 0
ax1.imshow(horizontal_flip)
ax1.set_title("Original Image")
ax2 = fig.add_subplot(gs[0, 1]) # row 0, col 1
ax2.imshow(pol)
ax2.set_title("Polar Transformation")
plt.show()

Blue Image from make_lupton_rgb

Getting a very blue image when trying to stack three bands of FITS images, not sure why blue is coming across more than the others and unsure how to adjust individually
import numpy as np
from astropy.io import fits
from astropy.visualization import SqrtStretch
from astropy.visualization import ZScaleInterval
from astropy.visualization import make_lupton_rgb
from matplotlib import pyplot as plt
forCasting = np.float_()
r=fits.open('...Directory_to_file/Horsehead_Red.fts')[0].data
g=fits.open('...Directory_to_file/Horsehead_Green.fts')[0].data
b=fits.open('...Directory_to_file/Horsehead_Blue.fts')[0].data
r = np.array(r,forCasting)
g = np.array(g,forCasting)
b = np.array(b,forCasting)
stretch = SqrtStretch() + ZScaleInterval()
r = stretch(g)
g = stretch(b)
b = stretch(r)
plt.imshow(r, origin='lower')
plt.imshow(g, origin='lower')
plt.imshow(b, origin='lower')
lo_val, up_val = np.percentile(np.hstack((r.flatten(), g.flatten(), b.flatten())), (10, 80))
stretch_val = up_val - lo_val
rgb_default = make_lupton_rgb(r, g, b, minimum=lo_val, stretch=stretch_val, Q=0, filename="provafinale.png")
plt.imshow(rgb_default, origin='lower')
plt.show()
The resulting image in question:

How to calculate the average grayscale profile of an image?

I would like to calculate the average grayscale profile of an image.
In my next code I have the evolution of the grayscale of all the pixels of the image, but how to make the average? To obtain a single curve, the average of all the others. Thank you
import imageio
import numpy as np
from matplotlib.pyplot import *
from matplotlib import pyplot as plt
img = imread("lion.jpg")
#
red = img[:,:,0]
green = img[:,:,1]
blue = img[:,:,2]
#print(np.mean(img)
line = red[:,:]
#here How to calculate the average grayscale profile?
figure(figsize=(8,4))
plot(line)
plt.show()
If I understand correctly, you want to have a profile of the greyscale image along both directions of the image.
import numpy as np
from matplotlib import pyplot as plt
img = plt.imread("https://i.stack.imgur.com/9qe6z.png")
# convert to grayscale
gray = img.mean(axis=2)
# or
#gray = np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
# profile along x -> mean along y
prof_x = gray.mean(axis=0)
# profile along y -> mean along x
prof_y = gray.mean(axis=1)
fig, (ax, ay) = plt.subplots(nrows=2, sharex=True, sharey=True)
ax.plot(prof_x, label="x profile")
ay.plot(prof_y, color="C1", label="y profile")
fig.legend()
plt.show()

Combine picture and plot with matplotlib with alpha channel

I have a .png image with alpha channel and a random pattern generated with numpy.
I want to supperpose both images using matplotlib. The bottom image must be the random pattern and over this, I want to see the second image (attached in the end of the post).
The code for both images is the following:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Random image pattern
fig = plt.subplots(figsize = (20,4))
x = np.arange(0,2000,1)
y = np.arange(0,284,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(284,2000)
Z[0,0] = 0
Z[1,1] = 1
# Plot the density map using nearest-neighbor interpolation
plt.pcolormesh(X,Y,Z,cmap = cm.gray)
The result is the following image:
To import the image, I use the following code:
# Sample data
fig = plt.subplots(figsize = (20,4))
# Plot the density map using nearest-neighbor interpolation
plt.imread("good_image_2.png")
plt.imshow(img)
print(img.shape)
The image is the following:
Thus, the final result that I want is:
You can make an image-like array for Z and then just use imshow to display it before the image of the buttons, etc. Note that this only works because your png has an alpha channel.
Code:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Plot the density map using nearest-neighbor interpolation
img = plt.imread("image.png")
(xSize, ySize, cSize) = img.shape
x = np.arange(0,xSize,1)
y = np.arange(0,ySize,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(xSize,ySize)
Z[0,0] = 0
Z[1,1] = 1
# We need Z to have red, blue and green channels
# For a greyscale image these are all the same
Z=np.repeat(Z,3).reshape(xSize,ySize,3)
fig = plt.figure(figsize=(20,8))
ax = fig.add_subplot(111)
ax.imshow(Z, interpolation=None)
ax.imshow(img, interpolation=None)
fig.savefig('output.png')
Output:
You can also turn off axes if you prefer.
ax.axis('off')

Categories

Resources