I am trying to write a code that correct the V channel of my images by taking my first images as reference. But I am getting this error while trying to pass my correction value to all the pixel to the images.
I am not sure how to do it. How should I rewrite my code for that part? I tried and error a lot of times but still didnt managed to resolve the issue.
>>>
RESTART: C:/Users/xxxx/AppData/Local/Programs/Python/Python36/avergae.py
[0.0, 103.81328149045861, 102.25728890139274, 100.11808781708474, 102.70660218168091, 104.8367051139934, 99.823930500250071, 104.96426229104148, 101.85104381075587, 102.09709583116921, 99.400945032365726, 92.15991298604699, 101.19626441549323, 103.19529341359842, 101.34438951969196, 102.6448956449741, 94.161672541871852, 91.460941106879034, 101.18572887210487, 101.6783903260298, 90.000500755040008]
103.81328149
[0.0, 0.0, 1.5559925890658661, 3.6951936733738648, 1.1066793087777, -1.0234236235347964, 3.9893509902085356, -1.1509808005828717, 1.9622376797027385, 1.716185659289394, 4.4123364580928808, 11.653368504411617, 2.6170170749653749, 0.6179880768601862, 2.4688919707666486, 1.168385845484508, 9.6516089485867553, 12.352340383579573, 2.6275526183537323, 2.134891164428808]
[[ 38 38 38 ..., 37 37 36]
[ 38 37 38 ..., 38 38 38]
[ 39 39 39 ..., 38 38 38]
...,
[141 141 142 ..., 160 161 161]
[142 142 144 ..., 164 160 159]
[142 142 143 ..., 168 162 159]]
3648
5472
Traceback (most recent call last):
File "C:/Users/Lian Ming/AppData/Local/Programs/Python/Python36/avergae.py", line 49, in <module>
v[i,j] = v+int(deltaList[z])
ValueError: setting an array element with a sequence.
>>>
Code :
import cv2
import numpy as np
path = 'C:\\Users\\xxxx\\Desktop\\experiment\\aligned\\'
path1 = 'C:\\Users\\xxxx\Desktop\\experiment\\aligned\\New folder\\'
img1 = cv2.imread(path + 'aligned_IMG_1770.png')
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
h_reference, s_reference, v_reference = cv2.split(img1)
Average_V_Reference = np.average(v_reference) #get the average of V for my first images as a reference value to compare to the rest of images
def ValueMean(im_file): #Create a function that do the average on the V channel for all the images
im = cv2.imread(im_file)
im = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(im)
a = np.average(v)
return a
myList = [0.0]
deltaList = [0.0] #store it in deltalist
num_images = 20
for i in range(1770, 1790):
image_name = path + 'aligned_IMG_' + str(i) + '.png'
myList.append(ValueMean(image_name)) #store all the images average into a list
print(myList)
print(Average_V_Reference)
for z in range(1, num_images):
deltaList.append(z)
deltaList[z] = Average_V_Reference - myList[z] #Data for all the difference in average value compared to reference images
print(deltaList)
z=1
for k in range(1770,1790): #create a loop to recreate images based on the data i got
a = 'aligned_IMG_' + str(k)
image_name = path + a + '.png'
img_file = cv2.imread(image_name)
img_file = cv2.cvtColor(img_file, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(img_file)
print(v)
print(img_file[:,:,2].shape[0])
print(img_file[:,:,2].shape[1])
for i in range(img_file[:,:,2].shape[0]): #passing correction value to each pixel on the V channel
for j in range (img_file[:,:,2].shape[1]):
v[i,j] = v+int(deltaList[z])
z += 1
img_file = cv2.merge((h,s,v)) #Merge back the HSV channel
img_file = cv2.cvtColor(img_file, cv2.COLOR_HSV2BGR) #convert back to BGR and save
new_image_name = path1 + 'BrightnessHSV_%d'%i + '.png'
cv2.imwrite('new_image_name', new_image_name)
Changing the following line would solve it
v[i,j] = v[i,j] +int(deltaList[z])
Related
in my computer vision class, I am asked to write my convolution codes from scatch, and use Pillow to test my results. I verify my convolution results with Scipy, they agree except at the boundary, which I don't care that much at this moment. Then I converted some images into numpy arrays, applied convolutions, and used Image.fromarray to convert it back to image, I found that my result is really different from using Image.filter directly. Here is one of the images I am using:
Image.filter gives me which I think is nice. By when I do my own convolution and use Image.fromarray, it gives me
I am not sure where went wrong. Could anyone help me with it? Any hint is appreciated!
from PIL import Image
from PIL import ImageFilter
import sys
import numpy as np
from scipy.signal import convolve2d
from PIL import ImageCms
def convolve2d_color(A,B):
# A is the convolution kernel
# B is matrix representing RGB. B.shape = (n,m,3)
result = np.zeros(B.shape)
for i in range(3):
result[:, :, i] = convolve2d( B[:,:, i], A, 'same', 'fill' )
return result
im = Image.open(sys.argv[1])
C = np.zeros((3,3))
C[1][0] = -1
C[1][-1] = 1
# doing convolution to images
im_arr = np.asarray(im)/255.0
# print(im_arr[:,:,0])
im_conv = convolve2d_color(C, im_arr)
# print(im_conv[:,:,0])
print(np.uint8(im_conv[1:-1,1:-1,1]*255))
im_output = Image.fromarray(np.uint8(im_conv*255), mode="RGB")
profile = ImageCms.createProfile("sRGB")
im_output.save("save1.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())
profile = ImageCms.createProfile("sRGB")
im_pillow = im.filter(ImageFilter.Kernel((3,3), list(C.reshape(9,)), 1))
print(np.array(im_pillow)[1:-1,1:-1,1])
im_pillow.save("save2.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())
Run python3 pyfile.py image.jpg to see the result. I also print some matrices out:
# My convolution
[[246 246 236 ... 0 254 253]
[247 247 238 ... 255 254 255]
[248 249 236 ... 0 254 254]
...
[252 252 252 ... 0 14 4]
[ 2 0 254 ... 8 20 2]
[ 2 1 255 ... 12 14 253]]
# Image.filter
[[10 10 20 ... 1 2 3]
[ 9 9 19 ... 2 2 1]
[ 8 7 20 ... 1 2 2]
...
[ 5 5 4 ... 0 0 0]
[ 0 0 2 ... 0 0 0]
[ 0 0 1 ... 0 0 3]]
Many entries add up to 256, but some don't.
The main issue involves the conversion of im_conv to uint8.
Without clipping pixel values to range [0, 255], the negative values gets overflowed to high positive values when converting to uint8.
Correct conversion applies scaling by 255, rounding, clipping to [0, 255] and casting to uint8:
im_conv_as_uint8 = np.uint8(np.round(im_conv*255).clip(0, 255))
For getting the same result using Pillow, we have to flip the kernel matrix left/right.
I can't find it in the documentation, but according to the filtered output, it should be flipped left/right before converting it to a list:
C = C[:, ::-1] # Flip left/right
im_pillow = im.filter(ImageFilter.Kernel((3, 3), list(C.reshape(9,)), 1))
The following code sample shows that the outputs of SciPy and Pillow are equal (except for the margins):
from PIL import Image
from PIL import ImageFilter
import sys
import numpy as np
from scipy.signal import convolve2d
from PIL import ImageCms
def convolve2d_color(A, B):
# A is the convolution kernel
# B is matrix representing RGB. B.shape = (n,m,3)
result = np.zeros(B.shape)
for i in range(3):
result[:, :, i] = convolve2d(B[:, :, i], A, 'same', 'fill')
return result
im = Image.open('parrot.jpg')
C = np.zeros((3,3))
C[1][0] = -1
C[1][-1] = 1
# doing convolution to images
im_arr = np.asarray(im)/255.0
# print(im_arr[:,:,0])
im_conv = convolve2d_color(C, im_arr)
# print(im_conv[:,:,0])
im_conv_as_uint8 = np.uint8(np.round(im_conv*255).clip(0, 255))
print(im_conv_as_uint8[1:-1,1:-1,1])
im_output = Image.fromarray(im_conv_as_uint8, mode="RGB")
profile = ImageCms.createProfile("sRGB")
im_output.save("save1.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())
C = C[:, ::-1] # Flip left/right (required for getting correct result of im.filter)
profile = ImageCms.createProfile("sRGB")
im_pillow = im.filter(ImageFilter.Kernel((3, 3), list(C.reshape(9,)), 1))
print(np.array(im_pillow)[1:-1,1:-1,1])
im_pillow.save("save2.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())
# Check for equality (ignore the margins)
is_equal = np.array_equal(np.array(im_pillow)[1:-1,1:-1,1], im_conv_as_uint8[1:-1,1:-1,1])
print(is_equal) # True
im_conv_as_uint8:
Note:
Clipping the negative values to zero gives the same output as Pillow, but it may not be the best solution (because we are losing data).
We may apply linear transformation from range [-1, 1] to [0, 255]:
im_conv_as_uint8 = np.uint8(np.round((im_conv+1)/2*255).clip(0, 255))
I want to convert a list of pixel values to tensor, but I got an error. My code calculate the pixel values (RGB) for each detected object in the image. How we can convert the list to tensor??
my code:
cropped_images =[]
imgs = PIL.Image.open(img_path).convert('RGB')
#print(img_path)
image_width, image_height = imgs.size
imgArrays = np.array(imgs)
X = (xCenter*image_width)
Y = (yCenter*image_height)
W = (Width*image_width)
H = (Height*image_height)
cropped_image = np.zeros((image_height, image_width))
for i in range(len(X)):
x1, y1, w, h = X[i], Y[i], W[i], H[i]
x_start = int(x1 - (w/2))
y_start = int(y1 - (h/2))
x_end = int(x_start + w)
y_end = int(y_start + h)
temp = imgArrays[y_start: y_end, x_start: x_end]
cropped_image_pixels = torch.as_tensor(temp)
cropped_images.append(cropped_image_pixels)
stacked_tensor = torch.stack(cropped_images)
print(stacked_tensor)
the error:
RuntimeError Traceback (most recent call last)
<ipython-input-82-653a155c3b71> in <module>()
130
131 if __name__=="__main__":
--> 132 main()
2 frames
<ipython-input-80-670335a0656c> in __getitem__(self, idx)
76 cropped_image_pixels = torch.as_tensor(temp)
77 cropped_images.append(cropped_image_pixels)
---> 78 stacked_tensor = torch.stack(cropped_images)
79
80 print(stacked_tensor)
RuntimeError: stack expects each tensor to be equal size, but got [506, 343, 3] at entry 0 and [520, 334, 3] at entry 1
list of tensors has two tensors
and it's clear that both don't have same size
torch.stack(tensors, dim=0, *, out=None) → Tensor
Concatenates a sequence of tensors along a new dimension.
All tensors need to be of the same size.
you can use this pseudo code
import torchvision.transforms as transforms
.
.
.
.
temp=[]
for img_name in LIST:
img=cv2.resize(img,(H,W))
temp.append(img)
train_x=np.asarray(temp)
transform = transforms.Compose(
[transforms.ToTensor(),
check doc
I have multiples raster with pixel resolution 10 X 10 meters and the raster value is in float format and I want to keep the out raster value in float format only.
I want to calculate 5 x 5 window pixel averaging to remove the noise from images and create a smooth raster in python. I worked out on a below code from different sources of stackoverflow, but it not working and its producing error.
I would appreciate any help.
Below Code:
import time
import glob
import os
import gdal
import osr
import numpy as np
start_time_script = time.clock()
path_ras=r'D:\Firm_SM\F1A/'
for rasterfile in glob.glob(os.path.join(path_ras,'*.tif')):
rasterfile_name=str(rasterfile[rasterfile.find('IMG'):rasterfile.find('.tif')])
print ('Processing:'+ ' ' + str(rasterfile_name))
ds = gdal.Open(rasterfile,gdal.GA_ReadOnly)
ds_xform = ds.GetGeoTransform()
print (ds_xform)
ds_driver = gdal.GetDriverByName('Gtiff')
srs = osr.SpatialReference()
#srs.ImportFromEPSG(4726)
ds_array = ds.ReadAsArray()
sz = ds_array.itemsize
print ('This is the size of the neighbourhood:' + ' ' + str(sz))
h,w = ds_array.shape
print ('This is the size of the Array:' + ' ' + str(h) + ' ' + str(w))
bh, bw = 5,5
shape = (h/bh, w/bw, bh, bw)
print ('This is the new shape of the Array:' + ' ' + str(shape))
strides = sz*np.array([w*bh,bw,w,1])
blocks = np.lib.stride_tricks.as_strided(ds_array,shape=shape,strides=strides)
resized_array = ds_driver.Create(rasterfile_name + '_resized_to_52m.tif',shape[1],shape[0],1,gdal.GDT_Float32)
resized_array.SetGeoTransform((ds_xform[0],ds_xform[1]*2,ds_xform[2],ds_xform[3],ds_xform[4],ds_xform[5]*2))
resized_array.SetProjection(srs.ExportToWkt())
band = resized_array.GetRasterBand(1)
zero_array = np.zeros([shape[0],shape[1]],dtype=np.float32)
print ('I start calculations using neighbourhood')
start_time_blocks = time.clock()
for i in xrange(len(blocks)):
for j in xrange(len(blocks[i])):
zero_array[i][j] = np.mean(blocks[i][j])
print ('I finished calculations and I am going to write the new array')
band.WriteArray(zero_array)
end_time_blocks = time.clock() - start_time_blocks
print ('Image Processed for:' + ' ' + str(end_time_blocks) + 'seconds' + '\n')
end_time = time.clock() - start_time_script
print ('Program ran for: ' + str(end_time) + 'seconds')
Error massage:
This is the size of the neighbourhood: 4
This is the size of the Array: 106 144
This is the new shape of the Array: (21.2, 28.8, 5, 5)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-fbee5d0233b0> in <module>
21 strides = sz*np.array([w*bh,bw,w,1])
22
---> 23 blocks = np.lib.stride_tricks.as_strided(ds_array,shape=shape,strides=strides)
24
25 resized_array = ds_driver.Create(rasterfile_name + '_resized_to_52m.tif',shape[1],shape[0],1,gdal.GDT_Float32)
c:\python37\lib\site-packages\numpy\lib\stride_tricks.py in as_strided(x, shape, strides, subok, writeable)
101 interface['strides'] = tuple(strides)
102
--> 103 array = np.asarray(DummyArray(interface, base=x))
104 # The route via `__interface__` does not preserve structured
105 # dtypes. Since dtype should remain unchanged, we set it explicitly.
c:\python37\lib\site-packages\numpy\core\_asarray.py in asarray(a, dtype, order)
83
84 """
---> 85 return array(a, dtype, copy=False, order=order)
86
87
TypeError: 'float' object cannot be interpreted as an integer
I am a newbie to numpy. Today when I use it to work with linear regression, it shows as below:
KeyError Traceback (most recent call
last)
~/anaconda3/lib/python3.6/site-packages/autograd/numpy/numpy_extra.py
in new_array_node(value, tapes)
84 try:
---> 85 return array_dtype_mappings[value.dtype](value, tapes)
86 except KeyError:
KeyError: dtype('int64')
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call
last)
<ipython-input-4-aebe8f7987b0> in <module>()
24 return cost/float(np.size(y))
25
---> 26 weight_h, cost_h = gradient_descent(least_squares, alpha,
max_its, w)
27
28 # a)
<ipython-input-2-1b74c4f818f4> in gradient_descent(g, alpha, max_its,
w)
12 for k in range(max_its):
13 # evaluate the gradient
---> 14 grad_eval = gradient(w)
15
16 # take gradient descent step
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
gradfun(*args, **kwargs)
19 #attach_name_and_doc(fun, argnum, 'Gradient')
20 def gradfun(*args,**kwargs):
---> 21 return
backward_pass(*forward_pass(fun,args,kwargs,argnum))
22 return gradfun
23
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
forward_pass(fun, args, kwargs, argnum)
57 tape = CalculationTape()
58 arg_wrt = args[argnum]
---> 59 start_node = new_node(safe_type(getval(arg_wrt)),
[tape])
60 args = list(args)
61 args[argnum] = merge_tapes(start_node, arg_wrt)
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
new_node(value, tapes)
185 def new_node(value, tapes=[]):
186 try:
--> 187 return Node.type_mappings[type(value)](value, tapes)
188 except KeyError:
189 return NoDerivativeNode(value, tapes)
~/anaconda3/lib/python3.6/site-packages/autograd/numpy/numpy_extra.py
in new_array_node(value, tapes)
85 return array_dtype_mappings[value.dtype](value, tapes)
86 except KeyError:
---> 87 raise TypeError("Can't differentiate wrt numpy arrays
of dtype {0}".format(value.dtype))
88 Node.type_mappings[anp.ndarray] = new_array_node
89
TypeError: Can't differentiate wrt numpy arrays of dtype int64
I really have no idea about what is happened. I guess it might be related to the structure of array in numpy. Or did I forget to download any packages? Below is my original codes.
# import statements
datapath = 'datasets/'
from autograd import numpy as np
# import automatic differentiator to compute gradient module
from autograd import grad
# gradient descent function
def gradient_descent(g,alpha,max_its,w):
# compute gradient module using autograd
gradient = grad(g)
# run the gradient descent loop
weight_history = [w] # weight history container
cost_history = [g(w)] # cost function history container
for k in range(max_its):
# evaluate the gradient
grad_eval = gradient(w)
# take gradient descent step
w = w - alpha*grad_eval
# record weight and cost
weight_history.append(w)
cost_history.append(g(w))
return weight_history,cost_history
# load in dataset
csvname = datapath + 'kleibers_law_data.csv'
data = np.loadtxt(csvname,delimiter=',')
# get input and output of dataset
x = data[:-1,:]
y = data[-1:,:]
x = np.log(x)
y = np.log(y)
#Data Initiation
alpha = 0.01
max_its = 1000
w = np.array([0,0])
#linear model
def model(x, w):
a = w[0] + np.dot(x.T, w[1:])
return a.T
def least_squares(w):
cost = np.sum((model(x,w)-y)**2)
return cost/float(np.size(y))
weight_h, cost_h = gradient_descent(least_squares, alpha, max_its, w)
# a)
k = np.linspace(-5.5, 7.5, 250)
y = weight_h[max_its][0] + k*weight_h[max_its][1]
plt.figure()
plt.plot(x, y, label='Linear Line', color='g')
plt.xlabel('log of mass')
plt.ylabel('log of metabolic rate')
plt.title("Answer Of a")
plt.legend()
plt.show()
# b)
w0 = weight_h[max_its][0]
w1 = weight_h[max_its][1]
print("Nonlinear relationship between the body mass x and the metabolic
rate y is " /
+ str(w0) + " + " + "log(xp)" + str(w1) + " = " + "log(yp)")
# c)
x2 = np.log(10)
Kj = np.exp(w0 + w1*x2)*1000/4.18
print("It needs " + str(Kj) + " calories")
Could someone help me to figure it out? Thanks a lot.
Here's the important parts of your error:
---> 14 grad_eval = gradient(w)
...
Type Error: Can't differentiate wrt numpy arrays of dtype int64
Your gradient function is saying it doesn't like to differentiate arrays of ints, which makes some sense, since it probably wants more precision than an int can give. You probably need them to be doubles or floats. For a simple solution to this, I believe you can just change your initializer from:
w = np.array([0,0])
which is going to automatically cast those 0s as ints, to:
w = np.array([0.0,0.0])
Those decimals after the 0 will let it know you want floats. There's other ways to go about telling it what kind of array you want (https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.array.html), but this is a simple way.
In my code, I am trying to import a grayscale image (2D array) and then solve for the optical density (OD) based off an empirical formula I came up with. The optical density has a relationship with the grayscale value where OD = 0.51*((f-22.08)/(176.09-f))**(1./-1.519) where f is the grayscale value of each element in the array. Then, I converted it into an RGB image.
My problem is I am trying to run each individual element of the image array into an if statement. It does not enter the statement though. What I want to do is increase the intensity of each individual element or pixel value in R, G, and B based on what condition is met with the optical density. Say if it has an OD value that falls between b and c, it adds [128,0,0] to each element that satisfies that criteria.
t = Image.open("IMG_1.jpg").convert('L') #grayscale image
f = array(t) #Convert test image into an array
OD = 0.51*((f-22.08)/(176.09-f))**(1./-1.519) #Empirical Rodbard formula
OD[np.isnan(OD)] = 0
def to_rgb5(im):
OD.resize((OD.shape[0], OD.shape[1], 1))
return np.repeat(OD.astype(np.uint8), 3, 2)
cmap = plt.get_cmap('jet')
rgba_img = cmap(OD)
rgb_img = np.delete(rgba_img, 3, 2)
a = 0.08
b = 0.11
c = 0.15
if np.all(OD < a):
background_noise = rgb_img
if np.all(OD < b):
small = rgb_img + [128, 0, 0]
elif np.all(OD >= c):
large = rgb_img + [0, 0, 128]
Red = f + small
Green = f
Blue = f + large
I was able to get it work using the np.where suggested by #Stuart
t = Image.open("IMG_1.jpg").convert('L') #grayscale image
f = array(t) #Convert test image into an array
OD = 0.51*((f-22.08)/(176.09-f))**(1./-1.519) #Empirical Rodbard formula
OD[np.isnan(OD)] = 0
thB = 0.02
ththin = 0.11
ththick = 0.15
GSb = 162
GSthin = 150
GSthick = 145
if np.where(OD < ththin):
thresholded = threshold(f, GSthin, GSb)
def to_rgb1(thresholded):
thresholded.resize((thresholded.shape[0], thresholded.shape[1], 1))
return np.repeat(thresholded.astype(np.uint8), 3, 2)
cmap = plt.get_cmap('jet')
rgba_img1 = cmap(thresholded)
rgb_img1 = np.delete(rgba_img1, 3, 2)
view = rgb_img1[:, :, 2]
view[view < 0.1] += 128
thin = rgb_img1
if np.where(OD > ththick):
thresholded2 = threshold(f, threshmax = GSthick)
def to_rgb2(thresholded2):
thresholded2.resize((thresholded2.shape[0], thresholded2.shape[1], 1))
return np.repeat(thresholded2.astype(np.uint8), 3, 2)
cmap = plt.get_cmap('jet')
rgba_img2 = cmap(thresholded2)
rgb_img2 = np.delete(rgba_img2, 3, 2)
view2 = rgb_img2[:, :, 0]
view2[view2 > 0] += 128
thick = rgb_img2