Converting RGB to grayscale python - python

I have been converting rgb images to grayscale images, below is the code
import numpy
import glob
import cv2
import csv
import math
import os
import string
from skimage.color import rgb2gray
from PIL import Image
mylist = [f for f in glob.glob("*.jpg")]
for imagefile in mylist:
img_color = cv2.imread(imagefile)
image = cv2.resize(img_color,(100,100),interpolation = cv2.INTER_AREA)
img_gray = rgb2gray(image)
img_gray.flatten()
Im not getting the new image saved into my current folder.
Can anyone help me regarding this.

I think it is because of skimage. why dont you use just opencv.
import numpy
import glob
import cv2
import csv
import math
import os
import string
from skimage.color import rgb2gray
from PIL import Image
mylist = [f for f in glob.glob("*.jpg")]
for imagefile in mylist:
img_color = cv2.imread(imagefile)
image = cv2.resize(img_color,(100,100),interpolation = cv2.INTER_AREA)
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#img_gray = rgb2gray(image)
img_gray.flatten()
cv2.imwrite("gray"+imagefile,img_gray)

You could also do this in one step if you want by adding an additional parameter to imread like this:
gray = cv2.imread(imagefile, cv2.IMREAD_GRAYSCALE)
cv2.imshow('gray', gray)

Basically you need to add code for saving image file:
import numpy
import glob
import cv2
import csv
import math
import os
import string
from skimage.color import rgb2gray
from skimage.io import imsave # skimage method for saving image
from PIL import Image
mylist = [f for f in glob.glob("*.jpg")]
for imagefile in mylist:
img_color = cv2.imread(imagefile)
image = cv2.resize(img_color,(100,100),interpolation = cv2.INTER_AREA)
img_gray = rgb2gray(image)
img_gray.flatten()
imsave("gray"+imagefile, img_gray) # save the image
Or using opencv
img_gray = img_gray*255
cv2.imwrite("gray"+imagefile, img_gray.astype("uint8"))
But if you want to implement this entirely in skimage
import glob
from skimage.io import imread, imsave
from skimage.color import rgb2gray
from skimage.transform import resize
mylist = [f for f in glob.glob("*.jpg")]
for imagefile in mylist:
img_color = imread(imagefile)
image = resize(img_color, (100, 100))
img_gray = rgb2gray(image)
img_gray.flatten()
imsave("gray" + imagefile, img_gray)

Related

PIL won't load RGB Image

I am trying to load this image into python (I provided a link because its 75mb): https://drive.google.com/file/d/1usiKRN1JQaIxTTo_HTXPwUj8LeyR8CDc/view?usp=sharing
My current code is below, it loads the image and when you png.show() the image it displays it in RBG but when converted to a numpy array its shape is only (h, w) not (h, w, 3) for RGB.
Code:
import numpy as np
from PIL import Image
Image.MAX_IMAGE_PIXELS = 233280000
png = Image.open('world.png')
png.show()
png = np.array(png)
print(png.shape)
Try this instead:
import numpy as np
from PIL import Image
Image.MAX_IMAGE_PIXELS = 233280000
png = Image.open('world.png').convert('RGB')
png.show()
png = np.array(png)
print(png.shape)

Is there a Python algorithm to detect nucleii in GFP cells?

I have been trying to make an algorithm that can detect the nucleii in GFP cell scans like this one:
GFP Cell Scan
for months. I want it to be able to output:
desired_cell_tracking
Is there an existing library for doing this, or is there a way to train my own basic ML classifier for this?
(I attached starter code that detects just the cell masks (but not nucleii))
###############################
# This code uses cellpose library to create a mask for each cell in 2 png files of GFP-channel cell scans.
###############################
#~~~~~~~~~~~~~~~~~~~~~~~~~
# GFP cell detection original libraries
from skimage.io import imread
import numpy as np
import time, os, sys
import matplotlib.pyplot as plt
import matplotlib as mpl
import fnmatch
mpl.rcParams['figure.dpi'] = 300
from cellpose import utils, io
from skimage.measure import label, regionprops, regionprops_table
import pandas as pd
from PIL import Image, ImageChops
#~~~~~~~~~~~~~~~~~~~~~~~~~
# GFP cell nucleii detection libraries
from skimage import (filters, measure, morphology, segmentation)
from scipy import ndimage as ndi
from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
import cv2
#~~~~~~~~~~~~~~~~~~~~~~~~~
# Load images
print("Libraries imported")
GFP_files = []
GFP_files.append('03152021_GFP_cells_1_lowesy_quality.tif')
GFP_files.append('03152021_GFP_cells_2_lowesy_quality.tif')
GFP_files= sorted(GFP_files) #sorting files
plt.figure(figsize=(2,2))
img = np.array(Image.open(GFP_files[0]))
img2 = img
wid = img.shape[0]
hei = img.shape[1]
#~~~~~~~~~~~~~~~~~~~~~~~~~
# Detect GFP cells
from cellpose import models, io
import random
model = models.Cellpose(gpu=True, model_type='cyto')
channels = [2,0]
#~~~~~~~~~~~~~~~~~~~~~~~~~
# LOOPING THROUGH FILES
#defining a null array for number of cells.
imgname=[0]*len(GFP_files)
n_cell= [[2, 0]]*len(GFP_files)
seg_masks=np.zeros((len(GFP_files), wid,hei)) #saving mask as 3d array for all images
i=-1 #for indexing
kernel = np.ones((5,5), np.uint8)
print('Running...')
# THE BIG LOOP
for filename in GFP_files:
i+=1
img = np.array(Image.open(filename))
masks, flows, styles, diams = model.eval(img, diameter=30, channels=channels)
n_cell[i]= [filename,np.max(masks)]
seg_masks[i,:,:]= masks
imgname[i]=[filename]
im = np.copy(img[:,:,0])
im[masks==0]=0 #set main background threshold on
# 'im' now is a single-color-channel image that only has one of the cells in it, everything else is background.

Processing and then saving images with a for loop in python

I'm new in programming and I'd like to ask you how can I write my code so that it read all the pic whitin a directory, process it one by one, and then save the output images in another directory.
%pylab
%matplotlib inline
import cv2
import glob
import os
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
filename = [img for img in glob.glob("outp/*.png")]
flist=sorted(filename)
images = []
for img in flist:
n = cv2.imread(img, 0)
images.append(n)
blur = cv.GaussianBlur(n, (9,9), 0)
cv.imwrite(flist, blur) #definitly wrong!! but idk how to do it
You don't need to create a list of all the pixel data of all the images in memory, that is just wasteful of memory. So, remove the lines:
images = []
and
images.apoend(...)
Then change your imwrite() to overwrite the current image:
cv2.imwrite(img,blur)
Here's a more complete version:
#!/usr/bin/env python3
import cv2
import glob
import os
import numpy as np
import cv2
# Go to where the images are
os.chdir('outp')
# Get list of filenames to convert
files = glob.glob("*.png")
for file in files:
n = cv2.imread(file, 0)
blur = cv2.GaussianBlur(n, (9,9), 0)
cv2.imwrite('blurred_' + file, blur)
Try this way:
cv2.imwrite("mypicture.jpg", gray[y:y+h,x:x+w])

Why matplotlib.pyplot.imsave() and matplotlib.pyplot.imshow() image qualities are different? How to ensure the same quality?

It seems matplotlib.imsave() lightens the image when compared to that of matplotlib.imshow(). For example, look at the code below.
import imageio
import matplotlib.pyplot as plt
image = imageio.imread('image.jpg')
plt.imshow(image)
plt.imsave('image_new.jpg', image)
image_new = imageio.imread('image_new.jpg')
plt.imshow(image_new)
Saved image image_new.jpg (right) is slightly lighter than image.jpg (left).
image_source: https://c1.staticflickr.com/9/8191/8424182610_e23dcc6b4d_b.jpg
I am really ok with your result. so I try it with CV2 and matplotlib:
import imageio
import matplotlib.pyplot as plt
import numpy as np
import cv2; import os
p0 = os.getcwd()
image1 = plt.imread(p0+'\\2.jpg')
image = plt.imread(p0+'\\2.jpg')[:,:,0]
plt.subplot(141);plt.imshow(image1 );plt.title('Original image')
plt.imsave('image_plt.jpg',image )
imageio.imsave('image_imageio.jpg', image)
imagecv2 = image
cv2.imwrite('image_cv2.jpg',imagecv2 )
image_new = plt.imread('image_plt.jpg')[:,:,0]
plt.subplot(2,4,2);plt.title('read after save plt')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,6);plt.title('Diff original image with saved plt')
x=np.abs ( image - image_new)
plt.imshow(x,cmap ='gray')
image_cv2 = plt.imread('image_cv2.jpg')[:,: ]
plt.subplot(2,4,3);plt.title('read after save plt')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,7);plt.title('Diff original image with saved CV2')
x=np.abs ( image - image_cv2)
plt.imshow(x,cmap ='gray')
image_imageio = plt.imread('image_imageio.jpg')
plt.subplot(2,4,4);plt.title('read after save imageio')
plt.imshow(image_new,cmap ='gray')
plt.subplot(2,4,8);plt.title('Diff original image with saved imageio')
x=np.abs ( image - image_imageio)
plt.imshow(x,cmap ='gray')
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.savefig('diff.jpg')
Results:

PIL images converted to RGB, getting saved as plain black images (python)

I have images that I want to save in jpeg format, after shearing and editing them.
This is my function in python:
import numpy as np
from skimage import data, io, filter, color, exposure
import skimage.transform as tf
from skimage.transform import resize, rescale, rotate, setup, warp, AffineTransform
import os
from os import listdir
from os.path import isfile, join
from PIL import Image
def generateHoGSamples(path, readfile):
print "generating samples from " + path+"\\"+readfile
img = color.rgb2gray(io.imread(path+"\\"+readfile))
img = resize(img, (50,100))
filename = os.path.splitext(readfile)[0]
angles = [3, 0, -3]
shears = [0.13, 0.0, -0.13]
imgidx = 0
for myangle in angles:
myimg = rotate(img, angle=myangle, order=2)
for myshear in shears:
imgidx+=1
afine_tf = tf.AffineTransform(shear=myshear)
mymyimg = tf.warp(myimg, afine_tf)
outputimg = Image.fromarray(mymyimg)
# Saving as "jpg" without the following line caused an error
outputimg = outputimg.convert('RGB')
outputimg.save(path+"//"+str(imgidx)+".jpg", "JPEG")
But what happens instead is that all images are nothing but black.
What's the matter here?
Your image mymyimage goes from 0 to 1 and PIL is expecting an image with values between 0 and 255. During the truncation your jpeg image will have truncated values 0 or 1, resulting in black.
To fix that, just multiply mymyimg by 255, such as
outputimg = Image.fromarray(mymyimg*255)
Hope it helps.
Cheers

Categories