I have a tensor_fa nifti image with values [0,1] of data type FLOAT32. Originally tried to load in a local script using the xtk edge library. This showed a blank canvas. I've also tried increasing the range (multiply by 100 to range [0,100]) and changing this multiplied image to a INT32. When trying in slicedrop, the original image "loads", but any attempt at thresholding brings up the "drop files anywhere" message. Same for the image multiplied by 100. The INT32 image allows thresholding, but still displays no image. I've verified all three images in fslview and mricron (nifti viewers).
Additionally, I've tried setting volume min/max to 0/1 and lower/upper Thresholds to 0/1.
Basic nifti header info:
data_type FLOAT32 or INT32
dim1 121
dim2 145
dim3 121
dim4 1
datatype 16 or 8
pixdim1 1.5000000000
pixdim2 1.5000000000
pixdim3 1.5000000000
pixdim4 0.0000000000
cal_max 0.0000
cal_min 0.0000
file_type NIFTI-1+
scl_slope 1.000000
scl_inter 0.000000
The images are:
http://wagners.homeip.net/work/wrtensor_fa_orig.nii.gz (Original image)
http://wagners.homeip.net/work/wrtensor_fa.mul100.nii.gz (Multiplied by 100)
The image as int is named wrtensor_fa.nii.gz. Stackoverflow won't let me post a third link.
Any suggestions appreciated.
Further followup:
It appears the data is not truly [0,1]. It contains NaNs. When I convert the NaNs to a true value, for example -1, then the image can be displayed. However, I need to work with an unmodified image. One would think that volume.lowerThreshold and upperThreshold would do the trick.
Further followup #2:
I've been muddling through Chrome's javascript tools. On the page I'm working with, the first of three images (INT16) I can do a volume.filedata and recieve an ArrayBuffer. The second and third (both FLOAT32) return a NULL.
What about using isNan() inside arrayMinMax?
X.parser.prototype.arrayMinMax = function(data) {
var _min = Infinity;
var _max = -Infinity;
// buffer the length
var _datasize = data.length;
var i = 0;
for (i = 0; i < _datasize; i++) {
if(!isNaN(data[i])) {
var _value = data[i];
_min = Math.min(_min, _value);
_max = Math.max(_max, _value);
}
}
return [ _min, _max ];
};
I like this solution better than having a specific check in each file parser.
Does it sound good to you?
Thanks
Related
Im trying to build a NN in C++,
it is being trained on the MNIST handwritten numbers data set to classify a number from a 28*28 black and white image, i have done the same problem in python that worked with a decent success rate but i am trying to do it in c++ for fun, it has 784 inputs (1 for each pixel), 100 hidden and 10 output nodes, it has no biases and a learning rate of 0.3 this is the same as in the python one.
The NN takes in a vector of 784 pixel values normalised from 0.01 to 0.99 in grey scale of an image of a handwritten number and outputs a 10 dimensional vector to identify the image.
However in c++ it always outputs roughly 0.5 for all of the nodes after training. I have tested it with more hidden nodes, different learning rates and more training data but the more training data I trained it on the closer it gets to 0.5. I have also tested that all the functions and overloads work as intended. None of these have helped.
I understand that a CNN would probably work better in this situation but i do not fully understand how to program one.
Here is the training function:
void train(std::vector<double> inputs, std::vector<double> targets)
{
std::vector<std::vector<double>> inputs2D = {inputs};
std::vector<std::vector<double>> targets2D = {targets};
inputs2D = utils::transpose(inputs2D);
targets2D = utils::transpose(targets2D);
std::vector<std::vector<double>> hidden_in = utils::dot(ih_weight, inputs2D);
std::vector<std::vector<double>> hidden_out = utils::activation(hidden_in);
std::vector<std::vector<double>> final_in = utils::dot(ho_weight, hidden_out);
std::vector<std::vector<double>> final_out = utils::activation(final_in);
std::vector<std::vector<double>> output_error = targets2D + (-1* final_out);
std::vector<std::vector<double>> hidden_error = utils::dot(utils::transpose(ho_weight), output_error);
ho_weight = (learningRate * utils::dot((output_error * final_out * (1.0 + (-1.0 * final_out))), utils::transpose(hidden_out))) + ho_weight;
ih_weight = (learningRate * utils::dot((hidden_error * hidden_out * (1.0+(-1.0 * hidden_out))), utils::transpose(inputs2D))) + ih_weight;
}
and here is the full code and training data: here
it also includes the python file, and the c++ was compiled using c++ 11 with g++
I'm quite new to C++ so feel free to recommend any changes that would make my code better.
I have a series of 100 integer values which I need to reduce/subsample to 77 values for the purpose of fitting into a predefined space on screen. This gives a fraction of 77/100 values-per-pixel - not very neat.
Assuming the 77 is fixed and cannot be changed, what are some typical techniques for subsampling 100 numbers down to 77. I get a sense that it will be a jagged mapping, by which I mean the first new value is the average of [0, 1] then the next value is [3], then average [4, 5] etc. But how do I approach getting the pattern for this mapping?
I am working in C++, although I'm more interested in the technique than implementation.
Thanks in advance.
Either if you downsample or you oversample, you are trying to reconstruct a signal over nonsampled points in time... so you have to make some assumptions.
The sampling theorem tells you that if you sample a signal knowing that it has no frequency components over half the sampling frequency, you can continously and completely recover the signal over the whole timing period. There's a way to reconstruct the signal using sinc() functions (this is sin(x)/x)
sinc() (indeed sin(M_PI/Sampling_period*x)/M_PI/x) is a function that has the following properties:
Its value is 1 for x == 0.0 and 0 for x == k*Sampling_period with k == 0, +-1, +-2, ...
It has no frequency component over half of the sampling_frequency derived from Sampling_period.
So if you consider the sum of the functions F_x(x) = Y[k]*sinc(x/Sampling_period - k) to be the sinc function that equals the sampling value at position k and 0 at other sampling value and sum over all k in your sample, you'll get the best continous function that has the properties of not having components on frequencies over half the sampling frequency and have the same values as your samples set.
Said this, you can resample this function at whatever position you like, getting the best way to resample your data.
This is by far, a complicated way of resampling data, (it has also the problem of not being causal, so it cannot be implemented in real time) and you have several methods used in the past to simplify the interpolation. you have to constructo all the sinc functions for each sample point and add them together. Then you have to resample the resultant function to the new sampling points and give that as a result.
Next is an example of the interpolation method just described. It accepts some input data (in_sz samples) and output interpolated data with the method described before (I supposed the extremums coincide, which makes N+1 samples equal N+1 samples, and this makes the somewhat intrincate calculations of (in_sz - 1)/(out_sz - 1) in the code (change to in_sz/out_sz if you want to make plain N samples -> M samples conversion:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/* normalized sinc function */
double sinc(double x)
{
x *= M_PI;
if (x == 0.0) return 1.0;
return sin(x)/x;
} /* sinc */
/* interpolate a function made of in samples at point x */
double sinc_approx(double in[], size_t in_sz, double x)
{
int i;
double res = 0.0;
for (i = 0; i < in_sz; i++)
res += in[i] * sinc(x - i);
return res;
} /* sinc_approx */
/* do the actual resampling. Change (in_sz - 1)/(out_sz - 1) if you
* don't want the initial and final samples coincide, as is done here.
*/
void resample_sinc(
double in[],
size_t in_sz,
double out[],
size_t out_sz)
{
int i;
double dx = (double) (in_sz-1) / (out_sz-1);
for (i = 0; i < out_sz; i++)
out[i] = sinc_approx(in, in_sz, i*dx);
}
/* test case */
int main()
{
double in[] = {
0.0, 1.0, 0.5, 0.2, 0.1, 0.0,
};
const size_t in_sz = sizeof in / sizeof in[0];
const size_t out_sz = 5;
double out[out_sz];
int i;
for (i = 0; i < in_sz; i++)
printf("in[%d] = %.6f\n", i, in[i]);
resample_sinc(in, in_sz, out, out_sz);
for (i = 0; i < out_sz; i++)
printf("out[%.6f] = %.6f\n", (double) i * (in_sz-1)/(out_sz-1), out[i]);
return EXIT_SUCCESS;
} /* main */
There are different ways of interpolation (see wikipedia)
The linear one would be something like:
std::array<int, 77> sampling(const std::array<int, 100>& a)
{
std::array<int, 77> res;
for (int i = 0; i != 76; ++i) {
int index = i * 99 / 76;
int p = i * 99 % 76;
res[i] = ((p * a[index + 1]) + ((76 - p) * a[index])) / 76;
}
res[76] = a[99]; // done outside of loop to avoid out of bound access (0 * a[100])
return res;
}
Live example
Create 77 new pixels based on the weighted average of their positions.
As a toy example, think about the 3 pixel case which you want to subsample to 2.
Original (denote as multidimensional array original with RGB as [0, 1, 2]):
|----|----|----|
Subsample (denote as multidimensional array subsample with RGB as [0, 1, 2]):
|------|------|
Here, it is intuitive to see that the first subsample seems like 2/3 of the first original pixel and 1/3 of the next.
For the first subsample pixel, subsample[0], you make it the RGB average of the m original pixels that overlap, in this case original[0] and original[1]. But we do so in weighted fashion.
subsample[0][0] = original[0][0] * 2/3 + original[1][0] * 1/3 # for red
subsample[0][1] = original[0][1] * 2/3 + original[1][1] * 1/3 # for green
subsample[0][2] = original[0][2] * 2/3 + original[1][2] * 1/3 # for blue
In this example original[1][2] is the green component of the second original pixel.
Keep in mind for different subsampling you'll have to determine the set of original cells that contribute to the subsample, and then normalize to find the relative weights of each.
There are much more complex graphics techniques, but this one is simple and works.
Everything depends on what you wish to do with the data - how do you want to visualize it.
A very simple approach would be to render to a 100-wide image, and then smooth scale the image down to a narrower size. Whatever graphics/development framework you're using will surely support such an operation.
Say, though, that your goal might be to retain certain qualities of the data, such as minima and maxima. In such a case, for each bin, you're drawing a line of darker color up to the minimum value, and then continue with a lighter color up to the maximum. Or, you could, instead of just putting a pixel at the average value, you draw a line from the minimum to the maximum.
Finally, you might wish to render as if you had 77 values only - then the goal is to somehow transform the 100 values down to 77. This will imply some kind of an interpolation. Linear or quadratic interpolation is easy, but adds distortions to the signal. Ideally, you'd probably want to throw a sinc interpolator at the problem. A good list of them can be found here. For theoretical background, look here.
so i have this image processing program where i am using a linear regression algorithm to find a plane that best fits all of the points (x,y,z: z being the pixel color intensity (0-255)
Simply speaking i have this picture of ? x ? dimension. I run this algorithm and i get these A, B, C values. (3 float values)
then i go every pixel in the program and minus the pixel value with mod_val where
mod_val = (-A * x -B * y ) / C
A,B,C are constants while x,y is the pixel location in a x,y plane.
When the dimension of the picture is divisible by 100 its perfect but when its not the picture fractures. The picture itself is the same as the original but there is a diagonal line with color contrast that goes across the picture. The program is supposed to make the pixel color uniform from the center.
I tried running the picture where mod_val = 0 for not divisble by 100 dimension pictures and it copies a new picture perfectly. So i doubt there is a problem with storing and writing the read data in terms of alignment. (fyi this picture is a grey scale 8 bit.bmp)
I have tried changing the A,B,C values but the diagonal remains the same. The color of the image fragments within the diagonals change.
when i run 1400 x 1100 picture it works perfectly with the mod_val equation written above which is the most baffling part.
I spent a lot of time looking for rounding errors. They are virtually all floats. The dimension i used for breaking picture is 1490 x 1170.
here is a gragment of the code where i think a error is occuring:
int img_row = row_length;
int img_col = col_length;
int i = 0;
float *pfAmultX = new float[img_row];
for (int x = 0; x < img_row; x++)
{
pfAmultX[x] = (A * x)/C;
}
for (int y = 0; y < img_col; y++)
{
float BmultY = B*y/C;
for (int x = 0; x < img_row; x++, i++)
{
modify_val = pfAmultX[x] + BmultY;
int temp = (int) data.data[i];
data.data[i] += (unsigned char) modify_val;
if(temp >= 250){
data.data[i] = 255;
}
else if(temp < 0){
data.data[i] = 0;
}
}
}
delete[] pfAmultX;
The img_row, img_col is correct according to VS debugger mode
Any help would be greatly appreciated. I've been trying to find this bug for many hours now and my boss is telling me that i can't go back home until i find this bug.....
before algorithm (1400 x 1100, works)
after
before (1490 x 1170, demonstrates the problem)
after
UPDATE:
well i have boiled down the problem as something with the x coordinate after extensive testing.
This is because when i use large A or B values or both (C value is always ~.999) for 1400x1100 it does not create diagonals.
However, for the other image, large B values do not create diagonals but a fairly small - avg A value creates diagonals.
Whats even more, when i test a picture where x is disivible by 100 but y is divisible by 10. the answer is correct.
well in the end i found the solution. It was a problem due to the padding the the bitmap. When the dimension on the x was not divisible by 4 it would use padding which would throw off all of the x coordinates. This also meant that the row_value i received from the bmp header was the same as the dimension but not really the same in reality. I had to make a edit where i had to do: 4 * (row_value_from_bmp_header + 3)/ 4.
I am trying to convert a given Mat representing an RGB image with 8-bit depth to Lab using the function provided in the documentation:
cvtColor(source, destination, <conversion code>);
I have tried the following conversion codes:
CV_RGB2Lab
CV_BGR2Lab
CV_LBGR2Lab
I have received bizarre results each time around, with an "L" value of greater than 100 for some samples, literally <107, 125, 130>.
I am also using Photoshop to check the results - but given that 107 is beyond the accepted range of 0 ≤ L ≤ 100, I can not comprehend what my error is.
Update:
I'll post my overall results here:
Given an image (Mat) represented by 8-bit BGR, the image can be converted by the following:
cvtColor(source, destination, CV_BGR2Lab);
The pixel values can then be accessed in the following manner:
int step = destination.step;
int channels = destination.channels();
for (int i = 0; i < destination.rows(); i++) {
for (int j = 0; j < destination.cols(); j++) {
Point3_<uchar> pixelData;
//L*: 0-255 (elsewhere is represented by 0 to 100)
pixelData.x = destination.data[step*i + channels*j + 0];
//a*: 0-255 (elsewhere is represented by -127 to 127)
pixelData.y = destination.data[step*i + channels*j + 1];
//b*: 0-255 (elsewhere is represented by -127 to 127)
pixelData.z = destination.data[step*i + channels*j + 2];
}
}
If anyone is interested in the range of the other variables a and b I made a small program to test their range.
If you convert all the colors that are represented with RGB to the CieLab used in OpenCV the ranges are:
0 <=L<= 255
42 <=a<= 226
20 <=b<= 223
And if you're using RGB values in the float mode instead of uint8 the ranges will be:
0.0 <=L<= 100.0
-86.1813 <=a<= 98.2352
-107.862 <=b<= 94.4758
P.S. If you want to see how distinguishable (regarding human perception) is a LAB value from another LAB value, you should use the floating point. The scale used to keep the lab values in the uint8 ranges messes up with their euclidean distance.
This is the code I used (python):
L=[0]*256**3
a=[0]*256**3
b=[0]*256**3
i=0
for r in xrange(256):
for g in xrange(256):
for bb in xrange(256):
im = np.array((bb,g,r),np.uint8).reshape(1,1,3)
cv2.cvtColor(im,cv2.COLOR_BGR2LAB,im) #tranform it to LAB
L[i] = im[0,0,0]
a[i] = im[0,0,1]
b[i] = im[0,0,2]
i+=1
print min(L), '<=L<=', max(L)
print min(a), '<=a<=', max(a)
print min(b), '<=b<=', max(b)
That's because L value is in range [0..255] in OpenCV. You can simply scale this value to needed interval ([0..100] in your case).
I am not sure about João Abrantes's range on A and B.
The opencv documentation has clearly mentioned the CIE L*a*b*range.
8 bit images
Thus leading to a range of
0 <= L <= 255
0 <= a <= 255
0 <= b <= 255
In case anyone runs into the same issue:
Please note that in OpenCV (2.4.13), you can not convert CV_32FC3 BGR images into the Lab color space. That is to say:
//this->xImage is CV_8UC3
this->xImage.convertTo(FloatPrecisionImage, CV_32FC3);
Mat result;
cvtColor(FloatPrecisionImage, result, COLOR_BGR2Lab);
this->xImage = result;
will not work
while
Mat result;
cvtColor(this->xImage, result, COLOR_BGR2Lab);
result.convertTo(this->xImage, CV_32FC3);
works like a charm.
I did not track down the reason for said behavior; however it seems off to me, because this in effect puts limits on the image's quality.
I have a given color and want to create variations of it in terms of hue, saturation and lightness.
I found a webpage which creates variations the way I would like it (See http://coloreminder.com/). However, I do not entirely understand how these variations are created for an arbitrary color. From what I can tell from considering created variations at this home page, it seems not to be enough to simply change the HSL values separately to create variations.
Hence, I wanted to ask if anybody knows an approach for creating these variations, or ideally knows where to get a piece of code to adopt this kind of color variations creation in my own program?
I am using C++ and QT.
EDIT: Thank you for your replies! Actually the variations of the given homepage really only varies the HSL values separately in 10% steps. I got confused since I compared the values with HSV values in color picker of my program.
From what I can tell from considering created variations at this home page, it seems not to be enough to simply change the HSL values seperately to create variations.
Really? The interface seems to be clear enough about what modifications it makes. You can select "hue", "saturation" or "luminance" and it shows 9 variations on that channel. The following MATLAB script will plot the different variations in a similar way (although in the HSV color space, not HSL).
% display n variations of HTML-style color code.
function [] = colorwheel ( hex, n )
% parse color code.
rgb = hex2rgb(hex);
% render all variations.
h = figure();
for j = 1 : 3,
% build n variations on current channel.
colors = variantsof(rgb, j, n);
% display variations.
for i = 1 : n,
% generate patch of specified color.
I = zeros(128, 128, 3);
I(:,:,1) = colors(i, 1);
I(:,:,2) = colors(i, 2);
I(:,:,3) = colors(i, 3);
% render patches side-by-side to show progression.
imshow(I, 'parent', ...
subplot(3, n, (j-1)*n+i, 'parent', h));
end
end
end
% parse HTML-style color code.
function [ rgb ] = hex2rgb ( hex )
r = double(hex2dec(hex(1:2))) / 255;
g = double(hex2dec(hex(3:4))) / 255;
b = double(hex2dec(hex(5:6))) / 255;
rgb = [r g b];
end
% generate n variants of color on j-th channel.
function [ colors ] = variantsof ( rgb, j, n )
colors = zeros(n, 3);
for i = 1 : n,
% convert to HSV.
color = rgb2hsv(rgb);
% apply variation to selected channel.
color(j) = color(j) + ((i-1) / n);
if color(j) > 1.0,
color(j) = color(j) - 1.0;
end
% convert to RGB.
colors(i,:) = hsv2rgb(color);
end
% order colors with respect to channel.
if j > 1,
colors = sortrows(colors, j);
end
end
Using the "goldenrod" sample color, as:
colorwheel('daa520', 9);
I get:
The first row is a variation on hue, the second on saturation and the third on value. The outputs don't correspond exactly to the ones on the coloreminder.com, but this is explained by the difference in color space and exact value used in permutations.
Have you read through the documentation for QColor?
The QColor class itself provides plenty of useful functions for manipulating colors in pretty much any way you can think of, and the documentation itself explains some basic color theory as well.