Numpy array to PIL image format - python

I'm trying to convert an image from a numpy array format to a PIL one. This is my code:
img = numpy.array(image)
row,col,ch= np.array(img).shape
mean = 0
# var = 0.1
# sigma = var**0.5
gauss = np.random.normal(mean,1,(row,col,ch))
gauss = gauss.reshape(row,col,ch)
noisy = img + gauss
im = Image.fromarray(noisy)
The input to this method is a PIL image. This method should add Gaussian noise to the image and return it as a PIL image once more.
Any help is greatly appreciated!

In my comments I meant that you do something like this:
import numpy as np
from PIL import Image
img = np.array(image)
mean = 0
# var = 0.1
# sigma = var**0.5
gauss = np.random.normal(mean, 1, img.shape)
# normalize image to range [0,255]
noisy = img + gauss
minv = np.amin(noisy)
maxv = np.amax(noisy)
noisy = (255 * (noisy - minv) / (maxv - minv)).astype(np.uint8)
im = Image.fromarray(noisy)

Related

How to demonstrate the Gaussian Kernal used in opencv GausssianBlurr, using the instruction `GaussianBlur()` from OpenCV?

I want to demonstrate the Gaussian Kernel used in openCV. cv2.GaussianBlurr(img, kernel_size, sigma) for explanation purposes.
I know how to demonstrate the image which results after applying the blur, and that is not my objective here.
My objective is to demonstrate the kernel automatically for any used sigma, and any used kernel size!
I have seen a code(mentioned down) but I prefer to use something more related to instruction used in OpenCV, rather than just a general mathematical dependent approach.
The expected output kernel is something like this:
import cv2
import numpy as np
# Read Image
img_path = 'image.jpg'
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Gaussian Blurr
Kernel = np.ones((15,15))
sigma = 2
Blurred_Image = cv2.GaussianBlur(img, (Kernel.shape[0], Kernel.shape[1]), sigma)
Gaussian Kernel Manual Code:
def dnorm(x, mu, sd):
return 1 / (np.sqrt(2 * np.pi) * sd) * np.e ** (-np.power((x - mu) / sd, 2) / 2)
def gaussian_kernel(size, sigma=1, verbose=False):
kernel_1D = np.linspace(-(size // 2), size // 2, size)
for i in range(size):
kernel_1D[i] = dnorm(kernel_1D[i], 0, sigma)
kernel_2D = np.outer(kernel_1D.T, kernel_1D.T)
kernel_2D *= 1.0 / kernel_2D.max()
if verbose:
plt.imshow(kernel_2D, interpolation='none',cmap='gray')
plt.title("Image")
plt.show()
return kernel_2D
Here is one way in Python/OpenCV.
- Read the input
- Create a delta image (one white pixel in the center of a black background)
- Blur the image
- List item
- Resize the image to enlarge it
- Stretch the image to full dynamic range
- Save the result
import cv2
import numpy as np
import skimage.exposure as exposure
# create delta image
dims = 30
dims2 = 30 // 2
delta = np.zeros((dims,dims,3), dtype=np.float32)
delta[dims2:dims2+1, dims2:dims2+1] = (255,255,255)
# blur image
blur = cv2.GaussianBlur(delta, (0,0), sigmaX=5, sigmaY=5)
# resize 16x
dims4x = dims * 16
resized = cv2.resize(blur, (dims4x,dims4x), interpolation = cv2.INTER_AREA)
# stretch to full dynamic range
result = exposure.rescale_intensity(resized, in_range='image', out_range=(0,255)).astype(np.uint8)
# save image
cv2.imwrite('delta.png',delta)
cv2.imwrite('gaussian_blur_view.png',result)
# show the images
cv2.imshow("delta", delta)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Delta image:
Result:

Get contrast for each channel in an image opencv python

How to calculate each channel contrast in images?
Since they are lot of contrast definitions out there
Webar Contrast
Michelson Contrast
RMS contrast
I need to calculate these contrasts.
from PIL import Image
import numpy as np
from numpy import mean, sqrt, square
im = Image.open("leaf.jpg") # Image file name
pixels = list(im.getdata())
width, height = im.size
pixels = np.asarray([pixels[i * width:(i + 1) * width] for i in range(height)], dtype=int)
ch_1 = pixels[:,:,0]
ch_2 = pixels[:,:,1]
ch_3 = pixels[:,:,2]
rms_of_ch1 = sqrt(mean(square(ch_1)))
rms_of_ch2 = sqrt(mean(square(ch_2)))
rms_of_ch3 = sqrt(mean(square(ch_3)))

How to add noise using skimage

I have written a simple code to add noise to image:
import cv2
from skimage.util import *
img = cv2.imread("./A/0030050944.jpg")
img = random_noise(img, mode='poisson', seed=42, clip=False)
cv2.imwrite("test.jpg", img)
But this only gives a blank black image.
Check this code. It adds gaussian , salt-pepper , poisson and speckle noise in an image.
Parameters
----------
image : ndarray
Input image data. Will be converted to float.
mode : str
One of the following strings, selecting the type of noise to add:
'gauss' Gaussian-distributed additive noise.
'poisson' Poisson-distributed noise generated from the data.
's&p' Replaces random pixels with 0 or 1.
'speckle' Multiplicative noise using out = image + n*image,where
n is uniform noise with specified mean & variance.
import numpy as np
import os
import cv2
def noisy(noise_typ,image):
if noise_typ == "gauss":
row,col,ch= image.shape
mean = 0
var = 0.1
sigma = var**0.5
gauss = np.random.normal(mean,sigma,(row,col,ch))
gauss = gauss.reshape(row,col,ch)
noisy = image + gauss
return noisy
elif noise_typ == "s&p":
row,col,ch = image.shape
s_vs_p = 0.5
amount = 0.004
out = np.copy(image)
# Salt mode
num_salt = np.ceil(amount * image.size * s_vs_p)
coords = [np.random.randint(0, i - 1, int(num_salt))
for i in image.shape]
out[coords] = 1
# Pepper mode
num_pepper = np.ceil(amount* image.size * (1. - s_vs_p))
coords = [np.random.randint(0, i - 1, int(num_pepper))
for i in image.shape]
out[coords] = 0
return out
elif noise_typ == "poisson":
vals = len(np.unique(image))
vals = 2 ** np.ceil(np.log2(vals))
noisy = np.random.poisson(image * vals) / float(vals)
return noisy
elif noise_typ =="speckle":
row,col,ch = image.shape
gauss = np.random.randn(row,col,ch)
gauss = gauss.reshape(row,col,ch)
noisy = image + image * gauss
return noisy
From How to add noise (Gaussian/salt and pepper etc) to image in Python with OpenCV
possion noise
from PIL import Image
import numpy as np
from skimage.util import random_noise
im = Image.open("test.jpg")
# convert PIL Image to ndarray
im_arr = np.asarray(im)
# random_noise() method will convert image in [0, 255] to [0, 1.0],
# inherently it use np.random.normal() to create normal distribution
# and adds the generated noised back to image
noise_img = random_noise(im_arr, mode='possion', var=0.05**2)
noise_img = (255*noise_img).astype(np.uint8)
img = Image.fromarray(noise_img)
img.show()

B&W image to binary array

I want to convert my b&w image(.png) to binary array(black is 1 white is 0). I have written some code, but it's not working. Error says: argument 2 to map() must support iteration.
Here is my code:
from PIL import Image
from resizeimage import resizeimage
import sys
def threshold(col):
s = sum(col)
return int(s > 255 * 3 // 2)
img = Image.open("filename.png")
ratio = float((img.size[1]) / (img.size[0]))
img = resizeimage.resize_cover(img, [100, int(ratio * 100)])
pixels = img.getdata()
binary = list(map(threshold, img))
array2d = [binary[i * img.size[0] : (i+1) * img.size[0]] for i in range(img.size[1])]
print('\n'.join(''.join(map(str, line)) for line in array2d))
Here is the image:
You need to convert your image to grayscale first, since PIL opens it as RGB. Then, invert the 0 & 255 values. Then, you can convert the non-zero values to 1. Here's one way:
from PIL import Image
import numpy as np
img = Image.open('bw_circle.png').convert('L')
np_img = np.array(img)
np_img = ~np_img # invert B&W
np_img[np_img > 0] = 1
And an alternative way using PIL for the inversion:
from PIL import Image, ImageOps
import numpy as np
img = Image.open('bw_circle.png').convert('L')
img_inverted = ImageOps.invert(img)
np_img = np.array(img_inverted)
np_img[np_img > 0] = 1

How to remove noise after reading a raw image file using np.fromfile() method

I got to know RAW images are interleaved and each pixel holds the value of each R,G,B component. So I have written below code to read the RGB pixel values and reshaped the image array to make it RGB image. After then I am converting the image to a binary one to process further. After conversion when I am trying to display the image it seems to contains noise. Can anyone help me in removing the noise?
Python version: 3.6
CODE:
from scipy import misc
from scipy import ndimage
import numpy as np
import matplotlib.pyplot as plt
import math
from PIL import Image
import rawpy
import imageio
def convert_to_binary(img):
threshold = 150
img[img <= 30] = 0
img[img > 30] = 255
return img
def sobel_test(im):
dx = ndimage.sobel(im, 0) # horizontal derivative
dy = ndimage.sobel(im, 1) # vertical derivative
mag = np.hypot(dx, dy) # magnitude
print(np.max(mag))
mag *= 255.0 / np.max(mag) # normalize (Q&D)
print(mag)
misc.imsave('sobel.jpg', mag)
return mag
A = np.fromfile("ABC.raw", dtype='int8', sep="")
A = np.reshape(A, (756, 1008, 3))
print("A.shape: %d", A.shape)
print("A: ", A)
print("A[0]: ", A[0])
img_gray = np.dot(A[..., :3], [0.30, 0.59, 0.11])
print("img_gray :", img_gray)
print("img_gray shape: ", img_gray.shape)
print("img_gray size: ", img_gray.size)
sob_img = sobel_test(img_gray)
binary_img = convert_to_binary(sob_img)
plt.imshow(binary_img, cmap="gray")
plt.show()
INPUT RAW Image: https://drive.google.com/open?id=12LcQZyYWMg9_6T_n3gjy7kBadRGNMDdr
Output Image

Categories

Resources