I really need help on this error trying to capture frames from a video using opencv - iterable-unpacking

Error : ValueError: not enough values to unpack (expected 4, got 1)
while True:
ret, frame = video.read()
faces = face_cascade.detectMultiScale2(frame, 1.3, 5)
for x, y, w, h in faces:

Related

From numpy to geotif having a georeferenced box

I created a numpy array by calculating the density of dwellings within an area through the following code:
def myplot(x, y, z, s, bins=10000):
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins, weights=z)
heatmap = gaussian_filter(heatmap, sigma=s)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
return heatmap.T, extent
fig, axs = plt.subplots(2, 2)
# Generate some test data
x = buildings["x"]
y = buildings["y"]
weights = buildings["Area"]
sigmas = [0, 16, 32, 64]
for ax, s in zip(axs.flatten(), sigmas):
if s == 0:
ax.plot(x, y, weights, 'k.', markersize=5)
ax.set_title("Scatter plot")
else:
img, extent = myplot(x, y, weights, s)
ax.imshow(img, extent=extent, origin='lower', cmap=cm.jet)
ax.set_title("Smoothing with $\sigma$ = %d" % s)
plt.savefig('export_'+str(s)+'.png', dpi=150, bbox_inches='tight')
plt.show()
This is the result and works fine:
enter image description here
Now I need to save it as a geotif and I know the extreme coordinates of the box angles. I tried to do that using the following code:
# create a georeferenced box
transform = from_bounds(extent[0], extent[1],extent[2], extent[3], 10000, 10000)
# save the georeferenced tif
with rio.open('data.tif', 'w', driver='GTiff', height=10000, width=10000, count=1, dtype='float64', nodata=0, crs=32632, transform=transform) as dst:
dst.write(img, 1)
The problem is that the result is transpose and not on the right position. Could you help me to find the solution?
I tried to develop the code but did not work
You should simply use numpy.transpose on your array - it is a very fast operation that does not copy the array.
GDAL uses traditional C style raster coordinates. In numpy an array with shape (x, y) is x lines of y pixels, while in GDAL it is the other way around.
# save the georeferenced tif
with rio.open('data.tif', 'w', driver='GTiff', height=10000, width=10000, count=1, dtype='float64', nodata=0, crs=32632, transform=transform) as dst:
dst.write(img.tranpose(), 1)

How to make a colored video with im2single instead of im2uint in matlab

The code below makes a video from 600x600x28 matrix using im2unit8 but in some of the frames like the below image, the color distribution is different from the original one. This happened due to the use of im2uint8.
I tried to use im2single to address the issue but since it maps the matrix between 0 and 1 the video frames are all black. I am wondering is there any way to make a colored video with im2single function.
Orig = randi([1 1000],600,600,28);
x = im2uint8(mat2gray(Orig));
% x = im2single(mat2gray(Orig));
map = jet(256); % Use colormap with 256 colors (the default is 64).
x_all = zeros(size(x, 1), size(x, 2), 3, size(x, 3), 'uint8'); % Allocate space
for i=1:size(x,3)
x_all(:,:,:,i) = im2uint8(ind2rgb(x(:,:,i), map));
end
v = VideoWriter('1_3.avi');
v.FrameRate = 1;
open(v);
writeVideo(v,x_all);
close(v)
Original image
converted image by uint8

Can't get tensorflow dataset to be accepted by the model.fit function. Some problem with dimensionality

I'm trying to decode bitmaps using the line of code below
img = tf.image.decode_bmp(img, channels=3)
create a tf.dataset of image/label pairs out of it using the .map function
test_labeled_ds = test_list_ds.map(process_path)
and feed it into model.fit
model.fit(test_labeled_ds, epochs=10, validation_data=val_labeled_ds)
using the model architecture below
i = Input(shape=(40,40,3))
x = Conv2D(32, (3,3), strides=2, activation='relu') (i)
x = Conv2D(64, (3,3), strides=2, activation='relu') (x)
x = Conv2D(128, (3,3), strides=2, activation='relu') (x)
x = Flatten()(x)
x = Dense(512, activation = 'relu')(x)
x = Dropout(0.2)(x)
x = Dense(5, activation ='softmax')(x)
model = Model(i, x)
But when I run model.fit I get the following error
ValueError: Error when checking input: expected input_1 to have 4
dimensions, but got array with shape (40, 40, 3)
I've tried changing the input shape to things such as i = Input(shape=(1,40,40,3))
But then I get a different error in the model:
ValueError: Input 0 of layer conv2d_3 is incompatible with the layer:
expected ndim=4, found ndim=5. Full shape received: [None, 1, 40, 40,
3]
So it would appear that the tf.dataset is actually 4dims and it's correct that my input should be specified with 3 dims as per (40, 40, 3)
So why doesn't this work?
Do I have to do something to the dataset object before I feed it to the model?
For the benefit of anyone who may encounter this in the future, I've managed to find the problem. The clue is in the error message. I was confused as my model clearly stated that the input would be (40, 40, 3) and yet the error said that it expected 4 dims and got an input (40, 40, 3).
But that's the answer right there. The models 'fit' function expects a 4D input. I was trying to feed in the whole dataset object (which is a 3D object) and it was expecting 4D.
It expects 4D because the other dimension is the batch size, which is why when you batch up the dataset and feed that in, it suddenly works. Batching up the data, add that extra dimension.

IDL - Reshape 2D-Array to 3D-Array

In IDL I have an datacube containing (grayscale) images at different times: datacube[w, h, frames]. Now I want to convert that datacube into an animation using IDLFFVideoWrite, but the problem is, the Put-Method only eats frames of the sort frame[3, w, h].
How can I convert a single frame of my datacube into a fitting frame, that IDLffVideoWrite::Put will eat?
You have greyscale images, so we need to make all three bands (R, G, and B) just copies of the one band. REBIN and REFORM are the tools for "juggling dimensions" like that:
frame = rebin(reform(datacube[*, *, i], 1, w, h), 3, w, h)
As long as datacube is of byte data, frame will be suitable for IDLffVideoWrite::put.
UPDATE: editing answer because I have limited formatting options in a comment.
So you actually have a datacube of this form then:
datacube[w, h, 3 * n_frames]
So you should do this to datacube to make it easier to deal with:
datacube = transpose(reform(datacube, w, h, 3, n_frames), [2, 0, 1, 3])
Then, to get the ith frame, you can just do:
frame = reform(datacube[*, *, *, i])

Inexplicable results after using ind2sub in Matlab

I am having some problems in matlab i don't understand. The following piece of code analyses a collection of images, and should return a coherent image (and always did).
But since I've put an if-condition in the second for-loop (for optimisation purposes) it returns an interlaced image.
I don't understand why, and am getting ready to throw my computer out the window. I suspect it has something to do with ind2sub, but as far as i can see everything is working just fine! Does anyone know why it's doing this?
function imageMedoid(imageList, resizeFolder, outputFolder, x, y)
% local variables
medoidImage = zeros([1, y*x, 3]);
alphaImage = zeros([y x]);
medoidContainer = zeros([y*x, length(imageList), 3]);
% loop through all images in the resizeFolder
for i=1:length(imageList)
% get filename and load image and alpha channel
fname = imageList(i).name;
[container, ~, alpha] = imread([resizeFolder fname]);
% convert alpha channel to zeros and ones, add to alphaImage
alphaImage = alphaImage + (double(alpha) / 255);
% add (r,g,b) values to medoidContainer and reshape to single line
medoidContainer(:, i, :) = reshape(im2double(container), [y*x 3]);
end
% loop through every pixel
for i=1:(y * x)
% convert i to coordinates for alphaImage
[xCoord, yCoord] = ind2sub([x y],i);
if alphaImage(yCoord, xCoord) == 0
% write default value to medoidImage if alpha is zero
medoidImage(1, i, 1:3) = 0;
else
% calculate distances between all values for current pixel
distances = pdist(squeeze(medoidContainer(i,:,1:3)));
% convert found distances to matrix of distances
distanceMatrix = squareform(distances);
% find index of image with the medoid value
[~, j] = min(mean(distanceMatrix,2));
% write found medoid value to medoidImage
medoidImage(1, i, 1:3) = medoidContainer(i, j, 1:3);
end
end
% replace values larger than one (in alpha channel) by one
alphaImage(alphaImage > 1) = 1;
% reshape image to original proportions
medoidImage = reshape(medoidImage, y, x, 3);
% save medoid image
imwrite(medoidImage, [outputFolder 'medoid_modified.png'], 'Alpha', alphaImage);
end
I didn't include the whole code, just this function (for brevity's sake), if anyone needs more (for a better understanding of it), please let me know and i'll include it.
When you call ind2sub, you give the size [x y], but the actual size of alphaImage is [y x] so you are not indexing the correct location with xCoord and yCoord.

Resources