How to randomly mix two PyTorch tensors - list

I have two same-shaped PyTorch tensors A and B, and I'd like to create a same-shape "randomly mixed" tensor C where C[i,...] = A[i,...] with probability alpha or B[i,...] with probability 1-alpha. Is there some Pythonic way to do this compactly?

consider using torch.bernoulli to create a mask tensor:
import torch
prob = 0.8
x = torch.full((2, 6, 3), 10.2, dtype=torch.float)
y = torch.full((2, 6, 3), -1.6, dtype=torch.float)
mask = torch.bernoulli(torch.full(x.shape, prob)).int()
reverse_mask = torch.ones(x.shape).int() - mask
result = x * mask + y * reverse_mask
result is now:
[[[10.2000, 10.2000, 10.2000],
[10.2000, -1.6000, 10.2000],
[10.2000, 10.2000, -1.6000],
[-1.6000, 10.2000, -1.6000],
[10.2000, 10.2000, 10.2000],
[10.2000, 10.2000, 10.2000]],
[[10.2000, 10.2000, -1.6000],
[10.2000, 10.2000, 10.2000],
[10.2000, 10.2000, -1.6000],
[10.2000, -1.6000, 10.2000],
[-1.6000, 10.2000, 10.2000],
[10.2000, 10.2000, 10.2000]]]
Good Luck!

Related

Matplotlib exception in Django 1.11

I am using matplotlib with mpld3 library to draw a graph in django, but when I am creating a simple bar graph with the following code:
x=np.arange(2014, date.today().year+1, 1)
my_xticks = list(x)
educationData=np.array(getDatas(x, eType=[3, 4, 5]))
figEdu = plt.figure()
axE = figEdu.add_subplot(111)
plt.xticks(x, my_xticks)
plt.xlabel('Year')
plt.ylabel('#Participants')
plt.text(0.2, 0.9, '#Participants: '+str(np.sum(educationData)), ha='center', va='center', transform=axE.transAxes, fontsize=18, color='#009EF3', weight='bold')##00b3fe
plt.bar(x, educationData, color=['#009EF3'])
figHtmlEdu = mpld3.fig_to_html(figEdu)
plt.close()
figAwr = plt.figure()
axA = figEdu.add_subplot(111)
awarenessData=np.array(getDatas(x, eType=[1]))
plt.xticks(x, my_xticks)
plt.xlabel('Year')
plt.ylabel('#Participants')
plt.text(0.2, 0.9, '#Participants: '+str(np.sum(awarenessData)), ha='center', va='center', transform=axA.transAxes, fontsize=18, color='#FFAF27', weight='bold')##00a65a
plt.bar(x, awarenessData, color=['#FFAF27'])
figHtmlAwr = mpld3.fig_to_html(figAwr)
plt.close()
figTrn = plt.figure()
axT = figEdu.add_subplot(111)
trainingData=np.array(getDatas(x, eType=[2]))
plt.xticks(x, my_xticks)
plt.xlabel('Year')
plt.ylabel('#Participants')
plt.text(0.2, 0.9, '#Participants: '+str(np.sum(trainingData)), ha='center', va='center', transform=axT.transAxes, fontsize=18, color='#00E18C', weight='bold')##ffad00
plt.bar(x, trainingData, color=['#00E18C'])
figHtmlTrn = mpld3.fig_to_html(figTrn)
plt.close()
It's running fine for the first time but on refresh it's giving
RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread
So please help me with this exception.

How to fix the reprojection from EASE-2 grid product SMAP to geographic coordinates?

I'm have been working with SMAP data satellite, specially for moisture and soil proporties.
I follow the idea of use GDAL solve everything, and make something similar to this published in Link to first approach to download SMAP data
Modifing the code and testing:
import os
import h5py
import numpy as np
from osgeo import gdal, gdal_array, osr
# the file to download
https://n5eil01u.ecs.nsidc.org/SMAP/SPL4SMAU.003/2017.08.01/SMAP_L4_SM_aup_20170801T030000_Vv3030_001.h5
path = "/path/to/data"
h5File = h5py.File(path + "SMAP_L4_SM_aup_20170801T030000_Vv3030_001.h5", 'r')
data = h5File.get('Analysis_Data/sm_rootzone_analysis')
lat = h5File.get("cell_lat")
lon = h5File.get("cell_lon")
np_data = np.array(data)
np_lat = np.array(lat)
np_lon = np.array(lon)
num_cols = float(np_data.shape[1])
num_rows = float(np_data.shape[0])
xmin = np_lon.min()
xmax = np_lon.max()
ymin = np_lat.min()
ymax = np_lat.max()
xres = (xmax - xmin) / num_cols
yres = (ymax - ymin) / num_rows
nrows, ncols = np_data.shape
xres = (xmax - xmin) / float(ncols)
yres = (ymax - ymin) / float(nrows)
geotransform = (xmin, xres, 0, ymax, 0, -xres)
dataFileOutput = path + "sm_rootzone_analysis.tif"
output_raster = gdal.GetDriverByName('GTiff').Create(dataFileOutput, ncols, nrows, 1, gdal.GDT_Float32) # Open the file
output_raster.SetGeoTransform(geotransform)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
output_raster.SetProjection(srs.ExportToWkt())
output_raster.GetRasterBand(1).WriteArray(np_data) # Writes my array to the raster
del output_raster
So, using this approach, the result is a global map with many problems of projections, as for example the image below, produced by the python code above.
To compare with a correct data, the same image was extract from h5, using HEG nasa software.
If the data is really in the EASE2 Global grid, you shouldn't assign EPSG:4326 as a the coordinate system with lat/lon degrees in the geotransform.
If you convert the lat/lon coordinates to the EASE2 Grid at 9km, your geotransform should be something like:
geotransform = (-17367530.44516138, 9000, 0, 7314540.79258289, 0, -9000.0)
and the srs:
srs.ImportFromEPSG(6933)

Labelling in MLP

I have a problem with the labeling on the MLP, first I thought it would be the same as the SVM labeling but after trying the code below :
Mat labels(numSamples, 3 , CV_32FC1, Scalar(3,0));
labels.rowRange(0, numcar - 1) = Scalar (1.0);
labels.rowRange(numcar, numcar + numbus - 1) = Scalar (2.0);
labels.rowRange(numcar + numbus, numSamples) = Scalar (3.0);
decide that the predictions on the same value even if I had to replace the image with another image. After I searched for it turns out there's a difference. The label must use a vector,I do not know how to label it using vectors because I newbie in this case.
below is the code for training
Mat layers = Mat(4, 1 ,CV_32SC1);
int sz = data.cols;
layers.row(0) = Scalar(sz);
layers.row(1) = Scalar(10);
layers.row(2) = Scalar(10);
layers.row(3) = Scalar(3);
CvANN_MLP mlp;
CvANN_MLP_TrainParams params;
CvTermCriteria criteria;
criteria.max_iter = 1000;
criteria.epsilon = 0.0001;
criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
params.train_method = CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale = 0.5f;
params.bp_moment_scale = 0.5f;
params.term_crit = criteria;
mlp.create(layers, CvANN_MLP::SIGMOID_SYM);
mlp.train(data , labels ,Mat(),Mat(),params);
and predictions
Mat response(1, 3, cv_32FC1);
mlp.predict (sample, response);
cout << response << endl;
I here want to label cars, buses, and trucks.
Help me to solve this problem, thanks for attention

Setting an array element with a sequence (MFCC+fastDTW, Python)

I want to build Voice command project by using RPi and python. I use MFCC and fastDTW to match that voice but I got this error and I have no idea how to fix it. Here the code...
def fastdtw(x, y, radius=1, dist=lambda a, b: abs(a - b)):
min_time_size = radius + 2
if len(x) < min_time_size or len(y) < min_time_size:
return dtw(x, y, window = None, dist=dist)
x_shrinked = __reduce_by_half(x)
y_shrinked = __reduce_by_half(y)
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
window = __expand_window(path, len(x), len(y), radius)
return dtw(x, y, window, dist=dist)
def dtw(x, y, window=None, dist=lambda a, b: abs(a - b)):
len_x, len_y = len(x), len(y)
if window is None:
window = [(i, j) for i in xrange(len_x) for j in xrange(len_y)]
window = [(i + 1, j + 1) for i, j in window]
D = np.full((len_x+1, len_y+1), np.inf, dtype=('f4, i4, i4'))
D[0, 0] = (0, 0, 0)
for i, j in window:
D[i, j] = min((D[i-1, j][0], i-1, j), (D[i, j-1][0], i, j-1), (D[i-1, j-1][0], i-1, j-1), key=lambda a: a[0])
D[i, j][0] += dist(x[i-1], y[j-1])
path = []
i, j = len_x, len_y
while not (i == j == 0):
path.append((i-1, j-1))
i, j = D[i, j][1], D[i, j][2]
path.reverse()
return (D[len_x, len_y][0], path)
Run file:
from __future__ import absolute_import, division, print_function, unicode_literals
from features import mfcc
from features import logfbank
import scipy.io.wavfile as wav
import time
from numpy.linalg import norm
import unittest
import numpy as np
from fastdtw import fastdtw, dtw
import bisect
from six.moves import xrange
from collections import defaultdict
start = time.time()
(rate1,sig1) = wav.read("/home/pi/OpenCalculator.wav")
(rate2,sig2) = wav.read("/home/pi/voiceCommand.wav")
mfcc1 = mfcc(sig1,rate1)
mfcc2 = mfcc(sig2,rate2)
dist, path = fastdtw(mfcc1, mfcc2)
elapsed = time.time()-start
And this is error message:
Traceback (most recent call last):
File "/home/pi/test.py", line 23, in <module>
dist, path = fastdtw(mfcc1, mfcc2)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 20, in fastdtw
distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 16, in fastdtw
return dtw(x, y, window = None, dist=dist)
File "build/bdist.linux-armv7l/egg/fastdtw.py", line 34, in dtw
D[i, j][0] += dist(x[i-1], y[j-1])
ValueError: setting an array element with a sequence.
*** output of mccc is in numpy array form.
Please help....
You need to redefine distance to work with feature vectors instead of numbers (default distance works with numbers, not with vectors):
def mfcc_dist(a,b):
dist = 0
for x, y in zip(a,b):
dist = dist + (x - y) * (x - y)
return sqrt(dist)
dist, path = fastdtw(mfcc1, mfcc2, dist=mfcc_dist)
You can also use numpy.linalg.norm(a-b).
mfcc1 and mfcc2 should be list or numpy array. Do they have correct type?

OpenCV: 3D Pose estimation of color markers using StereoCamera system

I have a stereo camera system and correctly calibrate it using both, cv::calibrateCamera and cv::stereoCalibrate. My reprojection error seems to be okay:
Cam0: 0.401427
Cam1: 0.388200
Stereo: 0.399642
I check my calibration by calling cv::stereoRectify and transforming my images using cv::initUndistortRectifyMap and cv::remap. The result is shown below (Something strange I noticed is when displaying the rectified images there are usually artifacts in form of a deformed copy of the original image on one or sometimes even both images):
I also correctly estimate the position of my markers in pixel coordinates using cv::findContours on a thresholded HSV image.
Unfortunately, when I now try to cv::triangulatePoints my results are very poor compared to my estimated coordinates, especially in x-direction:
P1 = { 58 (±1), 150 (±1), -90xx (±2xxx) } (bottom)
P2 = { 115 (±1), -20 (±1), -90xx (±2xxx) } (right)
P3 = { 1155 (±6), 575 (±3), 60xxx (±20xxx) } (top-left)
Those are the results in mm in camera coordinates. Both cameras are positioned approximately 550 mm away from the checkerboard and the square size is 13 mm. Apparently, my results are not even close to what I expect (negative and huge z-coordinates).
So my questions are:
I followed the stereo_calib.cpp sample quite closely and I seem to at least visually obtain good result (see reprojection error). Why are my triangulation results so poor?
How can I transform my results to the real-world coordinate system so I can actually check my results quantitatively? Do I have to do it manually as shown over here, or is there some OpenCV functions for that matter?
Here is my code:
std::vector<std::vector<cv::Point2f> > imagePoints[2];
std::vector<std::vector<cv::Point3f> > objectPoints;
imagePoints[0].resize(s->nrFrames);
imagePoints[1].resize(s->nrFrames);
objectPoints.resize( s->nrFrames );
// [Obtain image points..]
// cv::findChessboardCorners, cv::cornerSubPix
// Calc obj points
for( int i = 0; i < s->nrFrames; i++ )
for( int j = 0; j < s->boardSize.height; j++ )
for( int k = 0; k < s->boardSize.width; k++ )
objectPoints[i].push_back( Point3f( j * s->squareSize, k * s->squareSize, 0 ) );
// Mono calibration
cv::Mat cameraMatrix[2], distCoeffs[2];
cameraMatrix[0] = cv::Mat::eye(3, 3, CV_64F);
cameraMatrix[1] = cv::Mat::eye(3, 3, CV_64F);
std::vector<cv::Mat> tmp0, tmp1;
double err0 = cv::calibrateCamera( objectPoints, imagePoints[0], cv::Size( 656, 492 ),
cameraMatrix[0], distCoeffs[0], tmp0, tmp1,
CV_CALIB_FIX_PRINCIPAL_POINT + CV_CALIB_FIX_ASPECT_RATIO );
std::cout << "Cam0 reproj err: " << err0 << std::endl;
double err1 = cv::calibrateCamera( objectPoints, imagePoints[1], cv::Size( 656, 492 ),
cameraMatrix[1], distCoeffs[1], tmp0, tmp1,
CV_CALIB_FIX_PRINCIPAL_POINT + CV_CALIB_FIX_ASPECT_RATIO );
std::cout << "Cam1 reproj err: " << err1 << std::endl;
// Stereo calibration
cv::Mat R, T, E, F;
double err2 = cv::stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1],
cameraMatrix[0], distCoeffs[0], cameraMatrix[1], distCoeffs[1],
cv::Size( 656, 492 ), R, T, E, F,
cv::TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
CV_CALIB_USE_INTRINSIC_GUESS + // because of mono calibration
CV_CALIB_SAME_FOCAL_LENGTH +
CV_CALIB_RATIONAL_MODEL +
CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5);
std::cout << "Stereo reproj err: " << err2 << std::endl;
// StereoRectify
cv::Mat R0, R1, P0, P1, Q;
Rect validRoi[2];
cv::stereoRectify( cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
cv::Size( 656, 492 ), R, T, R0, R1, P0, P1, Q,
CALIB_ZERO_DISPARITY, 1, cv::Size( 656, 492 ), &validRoi[0], &validRoi[1]);
// [Track marker..]
// cv::cvtColor, cv::inRange, cv::morphologyEx, cv::findContours, cv::fitEllipse, *calc ellipsoid centers*
// Triangulation
unsigned int N = centers[0].size();
cv::Mat pnts3D;
cv::triangulatePoints( P0, P1, centers[0], centers[1], pnts3D );
cv::Mat t = pnts3D.t();
cv::Mat pnts3DT = cv::Mat( N, 1, CV_32FC4, t.data );
cv::Mat resultPoints;
cv::convertPointsFromHomogeneous( pnts3DT, resultPoints );
Finally, resultPoints is supposed to contain column vectors of my 3D positions in camera coordinates.
Edit: I removed some unnecessary conversions to shorten the code
Edit2: The results I get using #marols suggested solution for triangulation
P1 = { 111, 47, 526 } (bottom-right)
P2 = { -2, 2, 577 } (left)
P3 = { 64, -46, 616 } (top)
My answer will focus on suggesting another solution to triangulatePoints. In case of stereo vision, you can use matrix Q returned by stereo rectification in following way:
std::vector<cv::Vec3f> surfacePoints, realSurfacePoints;
unsigned int N = centers[0].size();
for(int i=0;i<N;i++) {
double d, disparity;
// since you have stereo vision system in which cameras lays next to
// each other on OX axis, disparity is measured along OX axis
d = T.at<double>(0,0);
disparity = centers[0][i].x - centers[1][i].x;
surfacePoints.push_back(cv::Vec3f(centers[0][i].x, centers[0][i].y, disparity));
}
cv::perspectiveTransform(surfacePoints, realSurfacePoints, Q);
Please adapt following snippet to your code, I might made some mistakes, but the point is to create an array of cv::Vec3f's, each of them having following structure: (point.x, point.y, disparity between point on second image) and pass it to the perspectiveTransform method (see docs for more details). If you would like to get more into details of how matrix Q is created (basically it represents a "reverse" projection from an image to real world point) see "Learning OpenCV" book, page 435.
In the stereo vision system I have developed, described method works fine and gives proper results on even bigger calibration errors (like 1.2).
To project into real world coordinates system, you need the Projection camera matrix.
This can be done as:
cv::Mat KR = CalibMatrix * R;
cv::Mat eyeC = cv::Mat::eye(3,4,CV_64F);
eyeC.at<double>(0,3) = -T.at<double>(0);
eyeC.at<double>(1,3) = -T.at<double>(1);
eyeC.at<double>(2,3) = -T.at<double>(2);
CameraMatrix = cv::Mat(3,4,CV_64F);
CameraMatrix.at<double>(0,0) = KR.at<double>(0,0) * eyeC.at<double>(0,0) + KR.at<double>(0,1) * eyeC.at<double>(1,0) + KR.at<double>(0,2) * eyeC.at<double>(2,0);
CameraMatrix.at<double>(0,1) = KR.at<double>(0,0) * eyeC.at<double>(0,1) + KR.at<double>(0,1) * eyeC.at<double>(1,1) + KR.at<double>(0,2) * eyeC.at<double>(2,1);
CameraMatrix.at<double>(0,2) = KR.at<double>(0,0) * eyeC.at<double>(0,2) + KR.at<double>(0,1) * eyeC.at<double>(1,2) + KR.at<double>(0,2) * eyeC.at<double>(2,2);
CameraMatrix.at<double>(0,3) = KR.at<double>(0,0) * eyeC.at<double>(0,3) + KR.at<double>(0,1) * eyeC.at<double>(1,3) + KR.at<double>(0,2) * eyeC.at<double>(2,3);
CameraMatrix.at<double>(1,0) = KR.at<double>(1,0) * eyeC.at<double>(0,0) + KR.at<double>(1,1) * eyeC.at<double>(1,0) + KR.at<double>(1,2) * eyeC.at<double>(2,0);
CameraMatrix.at<double>(1,1) = KR.at<double>(1,0) * eyeC.at<double>(0,1) + KR.at<double>(1,1) * eyeC.at<double>(1,1) + KR.at<double>(1,2) * eyeC.at<double>(2,1);
CameraMatrix.at<double>(1,2) = KR.at<double>(1,0) * eyeC.at<double>(0,2) + KR.at<double>(1,1) * eyeC.at<double>(1,2) + KR.at<double>(1,2) * eyeC.at<double>(2,2);
CameraMatrix.at<double>(1,3) = KR.at<double>(1,0) * eyeC.at<double>(0,3) + KR.at<double>(1,1) * eyeC.at<double>(1,3) + KR.at<double>(1,2) * eyeC.at<double>(2,3);
CameraMatrix.at<double>(2,0) = KR.at<double>(2,0) * eyeC.at<double>(0,0) + KR.at<double>(2,1) * eyeC.at<double>(1,0) + KR.at<double>(2,2) * eyeC.at<double>(2,0);
CameraMatrix.at<double>(2,1) = KR.at<double>(2,0) * eyeC.at<double>(0,1) + KR.at<double>(2,1) * eyeC.at<double>(1,1) + KR.at<double>(2,2) * eyeC.at<double>(2,1);
CameraMatrix.at<double>(2,2) = KR.at<double>(2,0) * eyeC.at<double>(0,2) + KR.at<double>(2,1) * eyeC.at<double>(1,2) + KR.at<double>(2,2) * eyeC.at<double>(2,2);
CameraMatrix.at<double>(2,3) = KR.at<double>(2,0) * eyeC.at<double>(0,3) + KR.at<double>(2,1) * eyeC.at<double>(1,3) + KR.at<double>(2,2) * eyeC.at<double>(2,3);