Processing and then saving images with a for loop in python - 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])

Related

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.

Python image library, Select random pictures from files

Hi I need some help with something I'm working on, I have this code that gets 2 pictures from 2 different folders and pastes it over each other creating 1 final merged image, what I want though is to merge two randomly selected pictures from the separate directories, thanks
from PIL import Image
import os
import random
import numpy as np
img1 = Image.open("/Users/Liam/Pictures/1/dfd.jpg").convert("RGBA")
img2 = Image.open("/Users/Liam/Pictures/2/face.png").convert("RGBA")
img1.paste(img2, (0,0), mask = img2)
img1.show()
It is actually pretty easy, check my example below
from PIL import Image
import os
import random
import numpy as np
basedir1 = "/Users/Liam/Pictures/1/"
basedir2 = "/Users/Liam/Pictures/2/"
first_image_list = os.listdir(basedir1)
second_image_list = os.listdir(basedir2)
img1 = Image.open(os.path.join(basedir1, random.choice(first_image_list))).convert("RGBA")
img2 = Image.open(os.path.join(basedir2, random.choice(second_image_list))).convert("RGBA")
img1.paste(img2, (0,0), mask = img2)
img1.show()

Converting RGB to grayscale 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)

Importing all pictures from the directory

In this directory "C:\Users\KG\Documents\R\data" I have 40 folders that are named from s1 to s40, where in each of the folder there are 10 pictures (.png) of faces named as (1,2,..10). How to import collection of pictures - faces as a flattened array? I use the code below, but it provide me with the mistake (does not download pictures):
from skimage import io
ic = io.ImageCollection('C:/Users/KG/Documents/R/data/*/*.png')
ic = np.array(ic)
ic_flat = ic.reshape((len(ic), -1))
You can use PIL library :
from PIL import Image
import numpy as np
ic = []
for i in folders:
for j in images:
image = Image.open(i + j)
ic.append(np.asarray(image))
ic = np.array(ic)
where folders and images are arrays of string with names
Give this code a try:
import os
from skimage import io
import numpy as np
folder = 'C:/Users/KG/Documents/R/data'
images = [os.path.join(root, filename)
for root, dirs, files in os.walk(folder)
for filename in files
if filename.lower().endswith('.png')]
ic = []
for img in images:
ic.append(io.imread(img).flatten())

Read set of images into 4D Numpy array with dimension (num_img,channel, dim1, dim2)

I have a set of 1000 gray scale images (28x28), I want to read them into 4D numpy array (number of images, 1, img_dim1,img_dim2). Following is my code but it doesn't work properly. Any idea how I can fix the issue in the code?
from PIL import Image
import numpy as np
import os
mypath=os.path.dirname('path/to/directory/')
def load_dataset( ) :
data =np.zeros((1000,1,28,28), dtype=np.float64)
for fname in os.listdir(mypath):
pathname = os.path.join(mypath, fname)
img = Image.open(pathname)
data = np.dstack((data, img))
return data
data=load_dataset()
print(data.shape)
The problem has been solved by using append and adding a new axis np.newaxis
from PIL import Image
import numpy as np
import os
mypath=os.path.dirname('path/to/directory/')
def load_dataset( ) :
data =[]
for fname in os.listdir(mypath):
pathname = os.path.join(mypath, fname)
img = Image.open(pathname)
img1 = img[np.newaxis,:,:]
data.append(img1)
return data
data= load_dataset()
data_x=np.array(data)
print data_x.shape

Categories