I'm trying to add an alpha channel to an .exr file(RGB) using OpenEXR python library or OpenCV, couldn't figure out how. Here's where I am.
import OpenEXR,Imath,array,os
import numpy as np
def write_exr_alpha(dir,output_dir):
z_file = OpenEXR.InputFile(dir)
FLOAT = Imath.PixelType(Imath.PixelType.FLOAT)
(z,_,_) = [array.array('f', z_file.channel(Chan, FLOAT)).tolist() for Chan in ("R", "G", "B") ]
dw = z_file.header()['dataWindow']
sz = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
os.makedirs(os.path.dirname(output_dir), exist_ok=True)
#get alpha values
As = np.ones(np.array(z).shape)
pos = np.where(np.array(z) > 100)[0]
As[pos] = 0
zs = array.array('f',z).tobytes()
out = OpenEXR.OutputFile(output_dir, OpenEXR.Header(sz[0], sz[1]))
# write to .exr with alpha channel
out.writePixels({'R' : zs, 'G' : zs, 'B' : zs ,'A': As})
and OpenCV
import os,cv2
import numpy as np
def write_exr_alpha(dir,output_dir):
os.makedirs(os.path.dirname(output_dir), exist_ok=True)
image=cv2.imread(dir,cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
normal_b, normal_g, normal_r = cv2.split(image)
As = np.ones(normal_b.shape, dtype=normal_b.dtype)
pos = np.where(np.array(image[:,:,0]) > 100)
for i in range(0,len(pos)):
As[pos[0][i]][pos[1][i]]=0
image_out = cv2.merge((normal_r, normal_g, normal_b, As))
cv2.imwrite(output_dir,image_out)
Edit: A test sample.
Related
I am using this code to implement a region growing algorithm but instead of sklearn I want to use open 3d.This is the original code and below you will find the code that I am using.
import math
import numpy as np
from sklearn.neighbors import KDTree
unique_rows=np.loadtxt("test.txt")
tree = KDTree(unique_rows, leaf_size=2)
dist,nn_glob = tree.query(unique_rows[:len(unique_rows)], k=30)
def normalsestimation(pointcloud,nn_glob,VP=[0,0,0]):
ViewPoint = np.array(VP)
normals = np.empty((np.shape(pointcloud)))
curv = np.empty((len(pointcloud),1))
for index in range(len(pointcloud)):
nn_loc = pointcloud[nn_glob[index]]
COV = np.cov(nn_loc,rowvar=False)
eigval, eigvec = np.linalg.eig(COV)
idx = np.argsort(eigval)
nor = eigvec[:,idx][:,0]
if nor.dot((ViewPoint-pointcloud[index,:])) > 0:
normals[index] = nor
else:
normals[index] = - nor
curv[index] = eigval[idx][0] / np.sum(eigval)
return normals,curv
#seed_count = 0
#while seed_count < len(current_seeds)
def regiongrowing1(pointcloud,nn_glob,theta_th = 'auto', cur_th = 'auto'):
normals,curvature = normalsestimation(pointcloud,nn_glob=nn_glob)
order = curvature[:,0].argsort().tolist()
region = []
if theta_th == 'auto':
theta_th = 15.0 / 180.0 * math.pi # in radians
if cur_th == 'auto':
cur_th = np.percentile(curvature,98)
while len(order) > 0:
region_cur = []
seed_cur = []
poi_min = order[0] #poi_order[0]
region_cur.append(poi_min)
seedval = 0
seed_cur.append(poi_min)
order.remove(poi_min)
# for i in range(len(seed_cur)):#change to while loop
while seedval < len(seed_cur):
nn_loc = nn_glob[seed_cur[seedval]]
for j in range(len(nn_loc)):
nn_cur = nn_loc[j]
if all([nn_cur in order , np.arccos(np.abs(np.dot(normals[seed_cur[seedval]],normals[nn_cur])))<theta_th]):
region_cur.append(nn_cur)
order.remove(nn_cur)
if curvature[nn_cur] < cur_th:
seed_cur.append(nn_cur)
seedval+=1
region.append(region_cur)
return region
region1 = regiongrowing1(unique_rows,nn_glob)
This is the code that I want to change.And than to use the use of the normals and region growing function.
import math
import numpy as np
import open3d as o3d
pcd = o3d.io.read_point_cloud("C:0000.ply")
points = np.asarray(pcd.points)
pcd_tree = o3d.geometry.KDTreeFlann(points)
[k, idy, _] = pcd_tree.search_knn_vector_3d(pcd.points[1500], 200)
At first,I am a python beginner. I need to read my clean.wav(cut to 50 slices to haha0~haha49 .wav) and noise.wav ,doing a snr [5,10,15]. Then output the before and after's waveform and Spectrogram. But,teriminal always tell me RuntimeError: Error opening 'D:\python\pythonnoisy\add_white\haha0_white_snr5.wav': System error. However, I can see this file in my folder.
import os
import re
import sys
import wave
import librosa
import matplotlib
import numpy as np
import pylab as pl
import soundfile as sf
import matplotlib.pyplot as plt
from scipy.fftpack import fft
wavedir = r"D:\python"
noisydir = wavedir+"\\pythonnoisy"
noisedir = wavedir+"\\pythonnoise"
cleandir = wavedir+"\\pythonclean"
def add_noise(noisydir, noisedir, cleandir, snr): # noisy
noisewav = "white.wav"
noise, fs = sf.read(noisedir+"\\"+noisewav) # 讀取白雜訊.wav
noisy_splitdir = noisydir+"\\"+"add_"+noisewav[:-4]+"\\"
# 迴圈取原始wav檔資料夾裡所有檔案
for cleanwav in os.listdir(cleandir):
clean, Fs = sf.read(cleandir+"\\"+cleanwav) # 讀取原始.wav檔
# 取樣頻率:原始音檔==白雜訊&&時長:原始音檔<白雜訊
if fs == Fs and len(clean) <= len(noise):
cleanenergy = np.sum(np.power(clean, 2)) # 原始音檔Power(=振幅^2)
# 1<隨機生成長度<noise長-clean長+1
ind = np.random.randint(1, len(noise) - len(clean) + 1)
noiselen = noise[ind:len(clean) + ind]
noiseenergy = np.sum(np.power(noiselen, 2)) # 白雜訊Power
ratio2 = np.sqrt(
(cleanenergy / noiseenergy) / (np.power(10, snr * 0.1)))
noisyAudio = clean + noiselen * ratio2 # 混音振幅
# 混音路徑+檔名
noisywavname = noisy_splitdir + \
cleanwav[:-4]+"_"+noisewav[:-4]+"_snr"+str(snr)+".wav"
sf.write(noisywavname, noisyAudio, 44100) # 生成混音.wav
def draw_clean(cleandir, j):
f = wave.open(
r"D:\python\pythonclean\haha" + str(j) + ".wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
f.close()
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data.shape = -1, 2
wave_data = wave_data.T
time = np.arange(0, nframes) * (1.0 / framerate)
plt.subplot(4, 2, 7)
plt.plot(time, wave_data[0])
plt.xlabel("time(s)")
plt.subplot(4, 2, 8)
plt.specgram(wave_data[0], Fs=framerate)
plt.xlabel("time(s)")
def draw_noisy(noisydir, j):
noisydirr = noisydir+"\\add_white\\haha"
for k in range(5, 20, 5):
f = wave.open(r"D:\python\pythonnoisy\add_white\haha" +
str(j)+"_white_snr"+str(k)+".wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data.shape = -1, 2
wave_data = wave_data.T
time = np.arange(0, nframes) * (1.0 / framerate)
plt.subplot(4, 2, k/5*2-1)
plt.plot(time, wave_data[0])
plt.subplot(4, 2, k/5*2)
plt.specgram(wave_data[0], Fs=framerate)
wavedir = r"D:\python"
noisydir = wavedir+"\\pythonnoisy"
noisedir = wavedir+"\\pythonnoise"
cleandir = wavedir+"\\pythonclean"
level = [5, 10, 15]
for snr in level:
add_noise(noisydir, noisedir, cleandir, snr)
for j in range(0, 51):
draw_clean(cleandir, j)
draw_noisy(noisydir, j)
picture = noisydir+"\picture\hahawhite"+str(j)+".png"
plt.savefig(picture)
plt.close()
file location
terminal
I'm creating a heatmap for a CNN as per this tutorial.
In the last part:
def create_patiens_cam(case, plane):
patient_id = case['id']
mri = case['mri']
folder_path = f'./CAMS/{plane}/{patient_id}/'
if os.path.isdir(folder_path):
shutil.rmtree(folder_path)
os.makedirs(folder_path)
os.makedirs(folder_path + 'slices/')
os.makedirs(folder_path + 'cams/')
params = list(mrnet.parameters())
weight_softmax = np.squeeze(params[-2].cpu().data.numpy())
num_slices = mri.shape[1]
global feature_blobs
feature_blobs = []
mri = mri.to(device)
logit = mrnet(mri)
size_upsample = (256, 256)
feature_conv = feature_blobs[0]
h_x = F.softmax(logit, dim=1).data.squeeze(0)
probs, idx = h_x.sort(0, True)
probs = probs.cpu().numpy()
idx = idx.cpu().numpy()
slice_cams = returnCAM(feature_blobs[-1], weight_softmax, idx[:1])
for s in tqdm_notebook(range(num_slices), leave=False):
slice_pil = (transforms
.ToPILImage()(mri.cpu()[0][s] / 255))
slice_pil.save(folder_path + f'slices/{s}.png',
dpi=(300, 300))
img = mri[0][s].cpu().numpy()
img = img.transpose(1, 2, 0)
heatmap = (cv2
.cvtColor(cv2.applyColorMap(
cv2.resize(slice_cams[s], (256, 256)),
cv2.COLORMAP_JET),
cv2.COLOR_BGR2RGB)
)
result = heatmap * 0.3 + img * 0.5
pil_img_cam = Image.fromarray(np.uint8(result))
pil_img_cam.save(folder_path + f'cams/{s}.png', dpi=(300, 300))
I have created a folder "CAMS" in my 'mrnet' folder. However when running this last code (in jupyter notebook) I get no errors but no png's are being created. Anyone has any idea what could be wrong or where I could look to see what's wrong as I get no errors?
FULL CODE:
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 13 21:54:40 2021
#author: GlaDOS
"""
import os
import io
import requests
from PIL import Image
from torchvision import models, transforms
from torch.autograd import Variable
from torch.nn import functional as F
import numpy as np
import cv2
import pdb
from matplotlib import pyplot as plt
import sys
sys.path.append('C:/Users/GlaDOS/mrnet')
import shutil
import torch
import model
from dataloader import MRDataset
from tqdm import tqdm_notebook
task = 'acl'
plane = 'sagittal'
prefix = 'sag'
model_name = [name for name in os.listdir('C:/Users/GlaDOS/mrnet/models/')
if (task in name) and
(plane in name) and
(prefix in name)][0]
is_cuda = torch.cuda.is_available()
device = torch.device("cuda" if is_cuda else "cpu")
mrnet = torch.load(f'C:/Users/GlaDOS/mrnet/models/{model_name}')
mrnet = mrnet.to(device)
_ = mrnet.eval()
dataset = MRDataset('C:/Users/GlaDOS/mrnet/data/',
task,
plane,
transform=None,
train=False)
loader = torch.utils.data.DataLoader(dataset,
batch_size=1,
shuffle=False,
num_workers=0,
drop_last=False)
def returnCAM(feature_conv, weight_softmax, class_idx):
size_upsample = (256, 256)
bz, nc, h, w = feature_conv.shape
slice_cams = []
for s in range(bz):
for idx in class_idx:
cam = weight_softmax[idx].dot(feature_conv[s].reshape((nc, h*w)))
cam = cam.reshape(h, w)
cam = cam - np.min(cam)
cam_img = cam / np.max(cam)
cam_img = np.uint8(255 * cam_img)
slice_cams.append(cv2.resize(cam_img, size_upsample))
return slice_cams
patients = []
for i, (image, label, _) in tqdm_notebook(enumerate(loader), total=len(loader)):
patient_data = {}
patient_data['mri'] = image
patient_data['label'] = label[0][0][1].item()
patient_data['id'] = '0' * (4 - len(str(i))) + str(i)
patients.append(patient_data)
acl = list(filter(lambda d: d['label'] == 1, patients))
def create_patiens_cam(case, plane):
patient_id = case['id']
mri = case['mri']
folder_path = f'C:/Users/GlaDOS/mrnet/cams/{plane}/{patient_id}/'
if os.path.isdir(folder_path):
shutil.rmtree(folder_path)
os.makedirs(folder_path)
os.makedirs(folder_path + 'slices/')
os.makedirs(folder_path + 'cams/')
params = list(mrnet.parameters())
weight_softmax = np.squeeze(params[-2].cpu().data.numpy())
num_slices = mri.shape[1]
global feature_blobs
feature_blobs = []
mri = mri.to(device)
logit = mrnet(mri)
size_upsample = (256, 256)
feature_conv = feature_blobs[0]
h_x = F.softmax(logit, dim=1).data.squeeze(0)
probs, idx = h_x.sort(0, True)
probs = probs.cpu().numpy()
idx = idx.cpu().numpy()
slice_cams = returnCAM(feature_blobs[-1], weight_softmax, idx[:1])
for s in tqdm_notebook(range(num_slices), leave=False):
slice_pil = (transforms
.ToPILImage()(mri.cpu()[0][s] / 255))
slice_pil.save(folder_path + f'slices/{s}.png',
dpi=(300, 300))
img = mri[0][s].cpu().numpy()
img = img.transpose(1, 2, 0)
heatmap = (cv2
.cvtColor(cv2.applyColorMap(
cv2.resize(slice_cams[s], (256, 256)),
cv2.COLORMAP_JET),
cv2.COLOR_BGR2RGB)
)
result = heatmap * 0.3 + img * 0.5
pil_img_cam = Image.fromarray(np.uint8(result))
pil_img_cam.save(folder_path + f'cams/{s}.png', dpi=(300, 300))
Use seaborn:
import seaborn as sns
sns_plot.savefig('output.png')
I try to detect shift in image with fft2. I find a code to do that but I dont really understand why the shift value is incorrect.
Here is the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy import fftpack
import matplotlib.image as mpimg
import scipy.signal
def cross_image(im1, im2):
im1_gray = np.sum(im1.astype('float'), axis=2)
im2_gray = np.sum(im2.astype('float'), axis=2)
im1_gray -= np.mean(im1_gray)
im2_gray -= np.mean(im2_gray)
image1FFT = np.conjugate( np.fft.fft2(im1_gray) )
image2FFT = np.conjugate( np.fft.fft2(im2_gray) )
imageCCor = np.real( np.fft.ifft2( (image1FFT*image2FFT) ) )
return imageCCor
# return scipy.signal.fftconvolve(im1_gray, im2_gray[::-1,::-1], mode='same')
def plot_spectrum(im_fft):
from matplotlib.colors import LogNorm
# A logarithmic colormap
plt.imshow(np.abs(im_fft), norm=LogNorm(vmin=5))
plt.colorbar()
im = mpimg.imread('/home/xavier/0001.jpg')
plt.figure()
plt.imshow(im, plt.cm.gray)
plt.title('Original image')
xPixelShift = 25
yPixelShift = -7
row, col,channels = im.shape
relativeSize = np.floor( min( 1-abs(xPixelShift)/col, 1-abs(yPixelShift)/row ) * 10 ) /10
x0 = int( (col - col*relativeSize)/2 )
x1 = col-x0 + 1
y0 = int( (row - row*relativeSize)/2 )
y1 = row-y0 + 1
# not shifted ROI
image1 = im[y0:y1,x0:x1].copy()
plt.figure()
plt.imshow(image1, plt.cm.gray)
# shifted ROI
image2 = im[y0+yPixelShift:y1+yPixelShift,x0+xPixelShift:x1+xPixelShift].copy()
plt.figure()
plt.imshow(image2, plt.cm.gray)
imageCCorShift = cross_image(image1,image2)
plt.figure()
plt.imshow(imageCCorShift)
row, col,channels = image1.shape
yShift, xShift = np.unravel_index( np.argmax(imageCCorShift), (row,col) )
print("shift of image1 in x-direction [pixel]: " + str(xShift))
print("shift of image1 in y-direction [pixel]: " + str(yShift))
When I use that commented code, it works:
scipy.signal.fftconvolve(im1_gray, im2_gray[::-1,::-1], mode='same')
But when I use my code, it does work
image1FFT = np.conjugate( np.fft.fft2(im1_gray) )
image2FFT = np.conjugate( np.fft.fft2(im2_gray) )
imageCCor = np.real( np.fft.ifft2( (image1FFT*image2FFT) ) )
return imageCCor
What the scipy function fftconvolve do more than my code?
I am a python newer.
I write some code try to mix pics to a new pic.
I finish it, but it wastes too much time.
so I try to use Numba let the code work on my gpu.
but meet some warning and error
os Ubuntu 16
pyhton version 3.5
for i in piclist:
img = cv2.imread(str(filepath)+'/'+str(i))
print (i)
b,g,r = cv2.split(img)
bcolorlist.append(b)
gcolorlist.append(g)
rcolorlist.append(r)
#jit(nopython = True)
def select(bcolorlist,gcolorlist,rcolorlist):
for i in range(len(bcolorlist)):
b = bcolorlist[i].reshape(2073600,1)
g = gcolorlist[i].reshape(2073600,1)
r = rcolorlist[i].reshape(2073600,1)
bcolorlist[i] = b
gcolorlist[i] = g
rcolorlist[i] = r
bbb = np.concatenate(bcolorlist, axis=1)
ggg = np.concatenate(gcolorlist, axis=1)
rrr = np.concatenate(rcolorlist, axis=1)
newb = []
newg = []
newr = []
for line in bbb:
newb.append(np.argmax(np.bincount(line)))
newb = np.array(newb)
for line in ggg:
newg.append(np.argmax(np.bincount(line)))
newg = np.array(newg)
for line in rrr:
newr.append(np.argmax(np.bincount(line)))
newr = np.array(newr)
return newb,newg,newr
that work normally without #jit
but with #jit will show below message
test.py:61: NumbaWarning:
Compilation is falling back to object mode WITH looplifting enabled because Function "select" failed type inference due to: Invalid use of Function() with argument(s) of type(s): (reflected list(array(uint8, 2d, C)), axis=Literalint)
Update the code now by suggestion
for f in files:
if is_img((os.path.splitext(f)[1])):
piclist.append(f)
start = time.time()
for i in piclist:
img = cv2.imread(str(filepath)+'/'+str(i))
b,g,r = cv2.split(img)
bcolorlist.append(b)
gcolorlist.append(g)
rcolorlist.append(r)
bcolorlist = array(bcolorlist)
gcolorlist = array(gcolorlist)
rcolorlist = array(rcolorlist)
#jit(nopython = True)
def select(bcolorlist,gcolorlist,rcolorlist):
r_res = np.zeros((len(bcolorlist), 2073600, 1), dtype=np.uint8)
g_res = np.zeros((len(gcolorlist), 2073600, 1), dtype=np.uint8)
b_res = np.zeros((len(rcolorlist), 2073600, 1), dtype=np.uint8)
for i in range(len(bcolorlist)):
r_res[i] = rcolorlist[i].reshape(2073600,1)
g_res[i] = gcolorlist[i].reshape(2073600,1)
b_res[i] = bcolorlist[i].reshape(2073600,1)
r_res = r_res.reshape(2073600, len(rcolorlist))
g_res = g_res.reshape(2073600, len(gcolorlist))
b_res = b_res.reshape(2073600, len(bcolorlist))
newr = np.zeros((2073600), dtype=np.uint8)
newg = np.zeros((2073600), dtype=np.uint8)
newb = np.zeros((2073600), dtype=np.uint8)
for i in range(b_res[:,0].size):
newr[i] = np.argmax(np.bincount(r_res[i,:]))
newg[i] = np.argmax(np.bincount(g_res[i,:]))
newb[i] = np.argmax(np.bincount(b_res[i,:]))
return newb, newg, newr
b, g, r = select(bcolorlist,gcolorlist,rcolorlist)
newb = b.reshape(1920,1080)
newg = g.reshape(1920,1080)
newr = r.reshape(1920,1080)
img = cv2.merge([newb, newg, newr])
end = time.time()
print (end - start)
It's work normally!!!!
but it doesn't make the output image.....
Could I trouble you to give some advice?
Update - working example with rgb images as input. I didn't do image processing in Python in the past so this was a nice excursion. Some code below. Note that I added some input parameters to the function to make it more versatile. I also changed some variable names but that's just a matter of taste so don't worry.
import cv2
import numpy as np
from numba import njit
#njit
def select(b, g, r, n, w, h): # added number of input images, width and height
r_res = r.reshape(n, w*h) # flatten the images' rgb 2d arrays to 1d
g_res = g.reshape(n, w*h)
b_res = b.reshape(n, w*h)
newr = np.zeros((w*h), dtype=np.uint8)
newg = np.zeros((w*h), dtype=np.uint8)
newb = np.zeros((w*h), dtype=np.uint8)
for i in range(w*h): # this is what takes time...
newr[i] = np.argmax(np.bincount(r_res[:,i]))
newg[i] = np.argmax(np.bincount(g_res[:,i]))
newb[i] = np.argmax(np.bincount(b_res[:,i]))
newb = newb.reshape(w,h) # reshape back from 1d to 2d
newg = newg.reshape(w,h)
newr = newr.reshape(w,h)
return newb, newg, newr
imgs = ['D:/test/DSC02142.jpg', 'D:/test/DSC02606.jpg', 'D:/test/DSC01747.jpg']
bcolorlist, gcolorlist, rcolorlist = [], [], []
for i in imgs:
b, g, r = cv2.split(cv2.imread(i))
bcolorlist.append(b)
gcolorlist.append(g)
rcolorlist.append(r)
b = np.array(bcolorlist)
g = np.array(gcolorlist)
r = np.array(rcolorlist)
n, w, h = b.shape # assuming all images of equal width x height!
newb, newg, newr = select(b, g, r, n, w, h)
imgmerge = cv2.merge((newb, newg, newr))
cv2.imwrite('D:/test/output.jpg', imgmerge)
...produces weird stuff like this: