Python - Grayscale very low with a mask - python

I'm working on pictures that have been converted to grayscale with:
Image.open('image.png').convert('LA')
I add a mask and I plot my picture with it, but while I expect to get grayscale values between 0 and 255, the values are very low as you can see below. There must be something wrong with the format. What do I have to do to get values between 0 and 255?
import numpy as np
import Image
import cv2
import matplotlib.pyplot as plt
import numpy.ma as ma
mask = plt.imread("mask.png")
test = plt.imread("1.png")
width, high = tab.shape
matrix = np.reshape(tab, (width, high))
# I have to force the dimension...
tab = mask[::, ::, 0]
test = tes[::, ::, 0]
test_mask = np.ma.array(ma.masked_array(test, tab.max()-tab))
And this is the plot:

By using OpenCV it works...
img = cv2.imread('test.png',0)

Related

is there a correct way to plot this white pixel?

iam a beginner at python and image processing etc. I want to plot this white pixel. as i know the pixel color identifier for black is 0 and for white is 255. here's the image that i want to plot:
The Image
i try to print out the image ndarray with these following command:
#importing module
import cv2
import numpy as np
import matplotlib.pyplot as plt
import sys
#load image
img = cv2.imread('thin.png')
#image to nd.array
arr0 = np.array(img)
#finding white pixel
arr1 = np.where(arr0 == 255)
#indexing tuple, the printout arr1 is tuple with dtype=int64
tuple1 = arr1[0]
tuple2 = arr1[1]
tuple3 = arr1[2]
#defining x and y axis
x = np.array(tuple1)
y = np.array(tuple2)
z = np.array(tuple3)
plot = plt.plot(x,y)
plt.show()
this is what i get..
output image
i think it's very noisy but i dont have a clue. Thank you very much for help
I think there is some confusion in the dimensions of you array arr0. I think you should look at the indices of the white pixels:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#load image
img = cv2.imread('thin.png')
#image to nd.array
arr0 = np.array(img)
height, width, _ = arr0.shape
x = range(width)
y = [height - np.argwhere(arr0[:, i, 0]==255).mean() for i in x] # "height -" to reverse the y-axis
plt.plot(x,y)
plt.show()
Note: taking the mean because a vertical line can have more than one white pixel (also some won't have any, see picture below)
Output:

Image Reconstruction (Erosion and Dilation) both gives black image as output

I am trying to remove the black spots from a face of this image using the erosion methods.
I have implemented:
img = skimage.io.imread('blemish.jpeg')
img = skimage.color.rgb2gray(img)
img_inten = skimage.exposure.rescale_intensity(img,in_range=(50,100))
diliation_seed = img_inten.copy()
diliation_seed[1:-1,1:-1] = img_inten.min()
mask = img_inten
eroded_img = skimage.morphology.reconstruction(diliation_seed,mask,method='dilation')
matplotlib.pyplot.imshow(eroded_img,cmap='gray')
My output is always a black image in both the cases. What is going wrong here?
rgb2gray is outputting an image as a matrix of floats, with values in [0;1]
So the rescale_intensity is just outputting a matrix of 0, since you ask for values between 50 and 100 and there is none in the gray img.
you can fix it like this :
import skimage
from skimage import data, exposure, img_as_float
from skimage.morphology import reconstruction
import matplotlib.pyplot as plt
img = skimage.io.imread('blemish.jpeg')
gray_img = 255*skimage.color.rgb2gray(img) # multiply by 255 to get back in the [0;255] range
img_inten = exposure.rescale_intensity(gray_img,in_range=(50,100))
diliation_seed = img_inten.copy()
diliation_seed[1:-1,1:-1] = img_inten.min()
mask = img_inten
eroded_img = reconstruction(diliation_seed,mask,method='dilation')
plt.imshow(eroded_img,cmap='gray')
plt.show()

Dimming image in Python

I am trying to implement dimming method to dim a image by converting pixel values and using this equation X(new) = 0.5 * X(old)^2. I did some googling and but could not succeed. Here is my code:
import math
from PIL import Image
import numpy as np
from skimage import color, io
import matplotlib.pyplot as plt
def load(image_path):
out = plt.imread(image_path)
out = out.astype(np.float64) / 255
return out
def dim_image(image):
out = image.point(lambda x: x*0.5)
return out
def display(img):
# Show image
plt.figure(figsize = (5,5))
plt.imshow(img)
plt.axis('off')
plt.show()
image1 = load(image1_path)
image2 = load(image2_path)
display(image1)
display(image2)
new_image = dim_image(image1)
display(new_image)
You are trying to use .point on a numpy array, which doesn't exist. I assume you meant to reduce all color values by 50% to dim the image, in which case you should use np.dot (docs):
def dim_image(image):
out = np.dot(image, 0.5)
return out

Resize image with skimage library without stretching

Hey i am trying to resize an image without stretching it but adding white pixels instead. I looked arround but i found nothing specifying how that can be achieved from within skimage. So instead i used numpy to add the extra pixels before the resize as arrays of [float(255)].
from skimage.io import imread
from skimage.io import imsave
from skimage.transform import resize
from matplotlib import pyplot as plt
from pylab import cm
import numpy as np
from skimage import morphology
from skimage import measure
from scipy import misc
def process(file_):
im = imread(file_, as_grey=True)
#im = misc.imread(file_)
#im=np.fromfile(file_, dtype=np.int64)
#Filler to avoid stretching
orig_rows, orig_cols = im.shape
print orig_rows, orig_cols
if orig_rows < orig_cols:
for addition in range(0,orig_cols-orig_rows):
#adding white rows
lst = np.array(list(float(255) for x in range(0,orig_cols)))
im= np.vstack((im,lst))
if orig_rows > orig_cols:
for addition in range(0,orig_rows-orig_cols):
#adding white columns
lst = np.array(list([float(255)] for x in range(0,orig_rows)))
im= np.hstack((im,lst))
image = resize(im, (48, 48))
imsave('test.jpg',im)
imsave('test1.jpg',image)
plt.imshow(im, cmap=cm.gray)
plt.show()
When i view the image with pyplot it looks like this
We can see that the columns have been added, but after i save the image with
image = resize(im, (48, 48))
imsave('test.jpg',im)
imsave('test1.jpg',image)
The the images look like negatives, and the resized image looks completely white(next to the dark its invisible on the sites background). Any ideas?
The code below should work. Note that the padded areas' color is not exactly white in order to see the image boundaries in the uploaded image. For white padding set fill_cval = np.max(img).
def resize_padded(img, new_shape, fill_cval=None, order=1):
import numpy as np
from skimage.transform import resize
if fill_cval is None:
fill_cval = np.max(img)
ratio = np.min([n / i for n, i in zip(new_shape, img.shape)])
interm_shape = np.rint([s * ratio for s in img.shape]).astype(np.int)
interm_img = resize(img, interm_shape, order=order, cval=fill_cval)
new_img = np.empty(new_shape, dtype=interm_img.dtype)
new_img.fill(fill_cval)
pad = [(n - s) >> 1 for n, s in zip(new_shape, interm_shape)]
new_img[[slice(p, -p, None) if 0 != p else slice(None, None, None)
for p in pad]] = interm_img
return new_img
import numpy as np
import matplotlib.pylab as plt
from skimage.data import astronaut
from skimage.color import rgb2gray # using luminance
from skimage.io import imsave
img = rgb2gray(astronaut())
# set desired image size
out_size = (30, 100) # height, width
# set the color of the padded area. Here: "95% luminance"
fill_cval = np.max(img) * 0.95
resized_img = resize_padded(img, out_size, fill_cval=fill_cval)
imsave('img.png', img)
imsave('img_res.png', resized_img)

histogram equalization for colored image give error using python opencv

Error : Assertion failed (0 < cn && cn <= CV_CN_MAX) in merge
In the merge function
cv2.merge(channels,img2)
if the arguments are replaced as shown:
cv2.merge(img2,channels)
it will not give an error, but the histograms will be the same before and after equalization. What can I do in this piece of code.
Code:
import cv2,cv
import cv2.cv as cv
import numpy as np
from matplotlib import pyplot as plt
capture = cv.CaptureFromCAM(0)
img = cv.QueryFrame(capture)
img_size = cv.GetSize(img)
width,height = img_size
size = width,height,3
channels = np.zeros(size , np.uint8)
while (1):
img = cv.QueryFrame(capture)
img = np.asarray(img[:,:])
cv2.imshow("original",img)
hist = cv2.calcHist([img],[2],None,[256],[0,256])
#convert img to YCR_CB
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2YCR_CB)
#split image to Y, CR, CB
cv2.split(img2,channels)
#histogram equalization to Y-MATRIX
cv2.equalizeHist(channels[0],channels[0])
#merge this matrix to reconstruct our colored image
cv2.merge(channels,img2)
#convert this output image to rgb
rgb = cv2.cvtColor(img2,cv2.COLOR_YCR_CB2BGR)
hist2 = cv2.calcHist([rgb],[2],None,[256],[0,256])
plt.plot(hist)
plt.plot(hist2)
plt.show()
Instead of using split and merge, take advantage of numpy slicing.
img2[:, :, 0] = cv2.equalizeHist(img2[:, :, 0])
# or run a small loop over each channel
you got the split() wrong here. it returns the channels.
since you don't catch the return values, your channels are not initialized
>>> import cv2
>>> help(cv2.split)
Help on built-in function split in module cv2:
split(...)
split(m[, mv]) -> mv
so it should look like:
channels = cv2.split(img2)
and please, avoid the old cv api, instead stick with cv2 consistently. (use cv2.VideoCapture, not cv.CaptureFromCAM)

Categories