I have a high resolution image with a size of 1024x1024.
I am trying to downscale it to 256x256 with a code below but it gives unwanted artifacts in the top row.
Here is the python code I tried.
img = np.array(Image.open('image.png'))
res = cv2.resize(img, dsize=(256, 256), interpolation=cv2.INTER_AREA)
Lanczos gives the same results below.
img = np.array(Image.open('image.png'))
res = cv2.resize(img, dsize=(256, 256), interpolation=cv2.INTER_LANCZOS4)
How should I remove this artifacts?
Image comes from the front end in PIL I preprocess it but it giving me a different shape than expected.
my code is
def preprocess(img):
img = np.array(img)
resized = cv2.resize(img, (254, 254))
img = tf.keras.preprocessing.image.img_to_array(resized)/255
img = np.array([img])
return img
this is a pil image
<PIL.JpegImagePlugin.JpegImageFile image mode=L size=2144x1805 at
0x229615E2488>
And when I preprocess it, it gives this shape
the shape of the test image is (1, 254, 254, 1)
and when I try the preprocess code outside of my project it works fine.
This means that your Network needs an image not in grayscale colors and you're unconsciously trimming that info. I suggest you to try resized = cv2.resize(img, (254, 254, 3)) instead of resized = cv2.resize(img, (254, 254)). Because otherwise your telling to the resize method implicitly that you want an image on grayscale and you'll miss that last dimension.
I wanted to utilize some images using CNN classification.
however, the problem is the image shape is different for example
for i in range(1,len(x_train)):
print(print(x_train_resize[i].shape))
this shows the images' shapes for all the images that i am using this gives output of
None
(100, 100)
None
(100, 100)
None
(100, 100, 3)
None
(100, 100, 4)
as shown above, is there a way to make the shapes of the images that i have all the same as
(100, 100, 1) or (100, 100, 3)
(100, 100) means grayscale image.
(100, 100, 3) means RGB image.
(100, 100, 4) means RGBA image.
If you have numpy grayscale image img_gray with shape (100,100) then you can duplicate layers to create (100, 100, 3) like in RGB
img_rgb = np.dstack((img_gray, img_gray, img_gray))
If you add alpha layer with values 255 then you get (100, 100, 4) like in RGBA
alpha = np.ones((100, 100), dtype='uint8') * 255
img_rgba = np.dstack((img_rgb, alpha))
If you have img_rgba with (100, 100, 4) then you can skip alpha layer to get img_rgb
img_rgb = img_rgba[:,:,:3]
to convert rgb to grayscale you could calculate
img_gray = (img_rgb[:,:,0] + img_rgb[:,:,1] + img_rgb[:,:,2]) // 3
but better is formula GRAY = 0.2126 * R + 0.7152 * G + 0.0722 * B
img_gray = int(0.2126 * img_rgb[:,:,0] + 0.7152 * img_rgb[:,:,1] + 0.0722 * img_rgb[:,:,2])
Wikipedia: Converting colour to greyscale
If you use OpenCV which also use numpy arrays then it has function to convert colors.
gray to RGB
img_rgb = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
gray to RBGA
img_rgba = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGBA)
RGB to RBGA
img_rgba = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2RGBA)
and in other direction
RGB to gray
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
RBGA to gray
img_gray = cv2.cvtColor(img_rgba, cv2.COLOR_RGBA2GRAY)
RGBA to RBG
img_rgb = cv2.cvtColor(img_rgba, cv2.COLOR_RGBA2RGB)
You could also use pillow Image.convert but it needs to
convert numpy array to pillow Image - img = Image.fromarray(array),
convert color - img = img.convert(...),
convert back pillow Image to numpy array - array = np.asarray(img).
Doc: Image.fromarray()
EDIT:
Minimal working example
import numpy as np
img_gray = np.zeros((100, 100), dtype='uint8')
# create image with cross
for y in range(100):
img_gray[y,y] = int(255 * (y/100))
img_gray[y,99-y] = int(255 * (y/100))
print('img_gray.shape:', img_gray.shape) # (100, 100)
img_rgb = np.dstack((img_gray, img_gray, img_gray))
print('img_rgb.shape:', img_rgb.shape) # (100, 100, 3)
alpha = np.ones((100, 100), dtype='uint8') * 255
img_rgba = np.dstack((img_rgb, alpha))
print('img_rgba.shape:', img_rgba.shape)
import matplotlib.pyplot as plt
plt.imshow(img_gray)
plt.show()
plt.imshow(img_rgb)
plt.show()
plt.imshow(img_rgba)
plt.show()
# --- OpenCV ---
import cv2
img_cv2_rgb = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
print('img_cv2_rgb.shape:', img_cv2_rgb.shape)
img_cv2_rgba = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGBA)
print('img_cv2_rgba.shape:', img_cv2_rgba.shape)
img_cv2_rgba2 = cv2.cvtColor(img_cv2_rgb, cv2.COLOR_RGB2RGBA)
print('img_cv2_rgba2.shape:', img_cv2_rgba2.shape)
cv2.imshow('gray', img_gray)
cv2.imshow('rgb', img_cv2_rgb)
cv2.imshow('rgba', img_cv2_rgba)
cv2.waitKey(0)
cv2.destroyAllWindows()
I'm new to opencv so don't mind me!
I want to convert an image which is a black and white image to gray scale image and save it by using cv2.imwrite(). The problem is that after I saved it to my local drive and read it back it returned as a 3 channels image. What is the problem here?
Here is my code
import cv2
image = cv2.imread("path/to/image/image01.jpg")
print(image.shape) # return (128, 128, 3)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(gray_image.shape) # return (128, 128)
cv2.imwrite("path/to/dir/gray01.jpg", gray_image)
new_gray_img = cv2.imread("path/to/dir/gray01.jpg")
print(new_gray_img.shape) # return (128, 128, 3)
here is the image i want to convert to gray.
cv2.imread loads images with 3 channels by default
You can replace the last two lines of code using:
new_gray_img = cv2.imread("path/to/dir/gray01.jpg",cv2.CV_LOAD_IMAGE_GRAYSCALE)
print(new_gray_img.shape)
Another method is to load image with scipy:
from scipy.ndimage import imread
new_gray_image=imread("path/to/dir/gray01.jpg")
Try to read the image directly in grayscale
cv2.imread("path/to/dir/gray01.jpg", 0)
import cv2
image = cv2.imread("path/to/image/image01.jpg")
print(image.shape) # return (128, 128, 3)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(gray_image.shape) # return (128, 128)
cv2.imwrite("path/to/dir/gray01.jpg", gray_image)
# here is the change
new_gray_img = cv2.imread("path/to/dir/gray01.jpg", 0)
print(new_gray_img.shape) # return (128, 128)
I want to resize an RGB image using Python 2.7. I tried using cv2.resize funcion, but it always returns a single channel image:
(Pdb) x = cv2.imread('image.jpg')
(Pdb) x.shape
(50, 50, 3)
(Pdb) x = cv2.resize(x, (40, 40))
(Pdb) x.shape
(40, 40)
I would like the final output of x.shape to be (40, 40, 3).
Is there a more pythonic way to resize the RGB image other than looping through the three channels and resizing each one separately?
Try this code:
import numpy as np
import cv2
image = cv2.imread('image.jpg')
cv2.imshow("Original", image)
"""
The ratio is r. The new image will
have a height of 50 pixels. To determine the ratio of the new
height to the old height, we divide 50 by the old height.
"""
r = 50.0 / image.shape[0]
dim = (int(image.shape[1] * r), 50)
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
cv2.imshow("Resized (Height) ", resized)
cv2.waitKey(0)