I'm trying to convert RGB image to HSI color space using visual c++ express 2010 and open CV 2.3.1 and have compiling error problem with this. Please can anyone help me with this and I need to know how can I use the matrix to save the values of H,S and I. Thanks in advance.
The codes that I use are.
#include "stdafx.h"
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
#include "cxcore.h"
#include "cv.h"
#include <highgui.h>
using namespace cv;
const string openCVpath = string(getenv("ProgramFiles"))+"\\OpenCV-2.3.1\\samples\\c\\";
int main (int, char**) {
//call image
Mat img1 = imread(openCVpath+"image1.jpg");
unsigned char *input = (unsigned char*)(img1.data);
// To get pixel values of i-th row and j-th cloumn,
double R,G,B,min,H,S,I;
int i,j;
const double PI= 3.14;
for(int i = 0;i < img1.rows ;i++){
for(int j = 0;j < img1.cols ;j++){
B = input[img1.step * j + i ] ;
G = input[img1.step * j + i + 1];
R = input[img1.step * j + i + 2];
}
// calculate the values of Hue, Saturation and Intensity
min = R;
if (G < min)
min = G;
if (B < min)
min = B;
I = (R+G+B)/3.0;
S = 1 - min/I;
if (S == 0.0)
{
H = 0.0;
}
else
{
H = ((R-G)+(R-B))/2.0;
H = H/sqrt((R-G)*(R-G) + (R-B)*(G-B));
H = acos(H);
if (B > G)
{
H = 2*PI - H;
}
H = H/(2*PI);
}
}
ifstream f("file.txt"); //...in your routine
//};
imshow("Image",img1);
cvWaitKey(0);
return 0;
};
why don't you use this :
cvtColor(img_rgb,img_hsv,CV_RGB2HSV);
also, see, OpenCV image conversion from RGB to HSV
I do not get a compilation error. But I needed to make the following changes to get your Programm to run:
B = input[img1.step * i + 3*j ] ;
G = input[img1.step * i + 3*j + 1];
R = input[img1.step * i + 3*j + 2];
I had to switch i and j because that is the way opencv organizes the memory. Also, you need to advance 3 bytes per pixel, because of the 3 rgb values.
Move the curly bracket in the next line to the line above ifstream f("file.txt");.
Otherwise you would only compute values for the last row of the image.
remove this line (I am not sure, what it is supposed to do):
ifstream f("file.txt");
And inside the for loops I added the following just to visualize the result, because so far you are not doing anything the computed results:
input[img1.step * i + 3*j ] = 255*H;
input[img1.step * i + 3*j + 1] = 255*S;
input[img1.step * i + 3*j + 2] = I;
Related
The product of the sequence of binomials reads
where {a_i} and {b_i} are coefficients in binomials.
I need to expand it to a polynomial
and use all coefficients {c_k} in the polynomial afterwards.
How to expand it efficiently? The speed has priority over the memory occupation because the expansion will be used many times.
What I tried
At present I just come up with an update scheme, which expands the polynomial right after absorbing one binomial.
This scheme needs two arrays — one for results up to i-1 and the other for results up to i.
Here is the C++ code for my naive scheme, but I think this question is irrelevant to what language is used.
#include <iostream>
#include <vector>
int main()
{
using namespace std;
// just an example, the coefficients are actually real numbers in [0,1]
unsigned d = 3;
vector<double> a;
vector<double> b;
a.resize(d, 1); b.resize(d, 1);
// given two arrays, a[] and b[], of length d
vector< vector<double> > coefficients(2);
coefficients[0].resize(d + 1);
coefficients[1].resize(d + 1);
if (d > 0) {
auto &coeff = coefficients[0]; // i = 0
coeff[0] = a[0];
coeff[1] = b[0];
for (unsigned i = 1; i < d; ++i) {// i : [1, d-1]
const auto ai = a[i];
const auto bi = b[i];
const auto &oldCoeff = coefficients[(i-1)%2];
auto &coeff = coefficients[i%2];
coeff[0] = oldCoeff[0] * ai; // j = 0
for (unsigned j = 1; j <= i; ++j) { // j : [1, i]
coeff[j] = oldCoeff[j] * ai + oldCoeff[j-1] * bi;
}
coeff[i+1] = oldCoeff[i] * bi; // j = i
}
}
const auto &coeff = coefficients[(d-1)%2];
for (unsigned i = 0; i < d; ++i) {
cout << coeff[i] << "\t";
}
cout << coeff[d] << '\n';
}
I want to generate 3 random numbers in the range 0 to 9 in a row which should sum up to a given fixed number. For example, for the given fixed sum 15, one possible solution would be (3, 8, 4). How can I do this ? Thanks.
We can:
First generate random float number a,b,c between 0 and 1
Get sum of a,b,c
Divide a,b,c by sum
Multiple a,b,c by given desired sum integer, and then round a,b,c to the nearest integer
See if sum(a, b, c) == given integer ? get result : try again
Check this demo:
Using boost random generator:
#include <iostream>
#include <time.h>
#include <iomanip>
#include <boost/random.hpp>
int main()
{
static time_t seed = time(0);
boost::random::mt19937 RandomNumGen(seed++);
boost::random::uniform_real_distribution<> Range(0, 1);
int Desired_Integer = 15;
int Rand_Max = 9;
int Max_Itr = 100000000;
int Count = 0;
int SumABC[3][10] = { 0 };
float bias = 0.5;
float a, b, c;
for (int Loop = 1; Loop <= Max_Itr; ++Loop)
{
a = Range(RandomNumGen);
b = Range(RandomNumGen);
c = Range(RandomNumGen);
float Sum = a + b + c;
a = a / Sum;
b = b / Sum;
c = c / Sum;
//Round to the nearest integer;
int aI = static_cast<int>(a * Desired_Integer + bias), bI = static_cast<int>(b * Desired_Integer + bias), cI = static_cast<int>(c * Desired_Integer + bias);
if (aI <= Rand_Max && bI <= Rand_Max && cI <= Rand_Max && aI + bI + cI == Desired_Integer)
{
SumABC[0][aI]++;
SumABC[1][bI]++;
SumABC[2][cI]++;
Count++;
}
}
int PaddingWidth = 10;
std::cout << "\n" << Count << " in " << Max_Itr << " loops get desired outcome. \nDistribution of a,b,c: \n";
std::cout << "Number" << std::setw(PaddingWidth) << "a" << std::setw(PaddingWidth) << "b" << std::setw(PaddingWidth) << "c" << std::endl;
for (int i = 0; i < 10; i++)
{
std::cout
<< i << std::setw(PaddingWidth + 8)
<< std::setprecision(4) << 100.0 * SumABC[0][i] / (float)Count << std::setw(PaddingWidth)
<< std::setprecision(4) << 100.0 * SumABC[1][i] / (float)Count << std::setw(PaddingWidth)
<< std::setprecision(4) << 100.0 * SumABC[2][i] / (float)Count << std::endl;
}
std::cout << "\n\n";
system("pause");
return 0;
}
Test efficiency:
When dealing with random variables it's a really good idea to check the work.
I simulated both answers. Xiaotao's not only has a different distribution, but different distribution frequencies. aI and bI have the same distribution but cI is significantly different. All three should have identical distributions.
Also, Kay's solution has the proper distribution as P(a)==1 s/b 1.25 times P(a)==1.
This is a deterministic solution and it has exactly the same statistics as Kay's
Further, the frequency of occurrence of each number looking at it purely from a probability POV from 0 to 9 is 4/73, 5/73, 6/73, 7/73, 8/73, 9/73, 10/73, 9/73, 8/73 and 7/73
A vector of all possible number sequences that sums to 15 is created. Then one element is chosen randomly. Each number set has an identical probability of being selected
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
vector<array<int, 3>> allLegalNumbers;
for (int i=0; i <= 9; i++) // go through all possible sets of 3 numbers from 0 to 9
for (int ii = 0; ii < DICE_SIDES; ii++)
for (int iii = 0; iii < DICE_SIDES; iii++)
if (i + ii + iii == DESIRED_NUMBER) // keep the ones that add up to 15
allLegalNumbers.push_back(array<int, 3> {i, ii, iii});
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, allLegalNumbers.size() - 1);
int sum[3][DICE_SIDES]{};
int sum_count = 0;
for (int Loop = 1; Loop < 100000000; ++Loop)
{
auto index = distribution(generator);
sum[0][allLegalNumbers[index][0]]++;
sum[1][allLegalNumbers[index][1]]++;
sum[2][allLegalNumbers[index][2]]++;
sum_count++;
}
for (int i = 0; i < DICE_SIDES; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.48 bI==0: 5.48 cI==0: 5.48
Percent of aI==1: 6.85 bI==1: 6.85 cI==1: 6.85
Percent of aI==2: 8.22 bI==2: 8.22 cI==2: 8.22
Percent of aI==3: 9.59 bI==3: 9.59 cI==3: 9.59
Percent of aI==4:10.96 bI==4:10.96 cI==4:10.96
Percent of aI==5:12.33 bI==5:12.33 cI==5:12.34
Percent of aI==6:13.69 bI==6:13.70 cI==6:13.70
Percent of aI==7:12.34 bI==7:12.33 cI==7:12.33
Percent of aI==8:10.96 bI==8:10.96 cI==8:10.95
Percent of aI==9: 9.59 bI==9: 9.59 cI==9: 9.58
*/
Xiaotao's answer simulation: Note the different distribution of cI v aI and bI
#include <iostream>
int main()
{
int SumI = 15;
int Rand_Max = 9;
float a, b, c;
int sum[3][10]{};
int sum_count = 0;
for (int Loop = 1; Loop < 100000000; ++Loop)
{
a = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
b = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
c = static_cast<float>(rand() % Rand_Max) / static_cast<float>(Rand_Max);
float Sum = a + b + c;
a = a / Sum;
b = b / Sum;
c = c / Sum;
//Round to the nearest integer;
int aI = static_cast<int>(a * SumI + 0.5), bI = static_cast<int>(b * SumI + 0.5), cI = static_cast<int>(c * SumI + 0.5);
if (aI <= Rand_Max && bI <= Rand_Max && cI <= Rand_Max && aI + bI + cI == SumI)
{
sum[0][aI]++;
sum[1][bI]++;
sum[2][cI]++;
sum_count++;
}
}
for (int i = 0; i < 10; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.84 bI==0: 5.83 cI==0: 5.84
Percent of aI==1: 5.30 bI==1: 5.31 cI==1: 5.31
Percent of aI==2: 7.43 bI==2: 7.43 cI==2: 6.90
Percent of aI==3: 9.55 bI==3: 9.54 cI==3: 9.28
Percent of aI==4:10.61 bI==4:10.61 cI==4:10.60
Percent of aI==5:15.64 bI==5:15.66 cI==5:15.39
Percent of aI==6:16.18 bI==6:16.18 cI==6:17.51
Percent of aI==7:11.41 bI==7:11.40 cI==7:10.88
Percent of aI==8: 9.82 bI==8: 9.81 cI==8:10.08
Percent of aI==9: 8.22 bI==9: 8.22 cI==9: 8.22
*/
Kay's answer does not exhibit this error. Here's that simulation:
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
// Don't use "using namespace" in production.
// I only use it to avoid the horizontal scrollbar.
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, DICE_SIDES - 1);
int sum[3][10]{};
int sum_count = 0;
for (int Loop = 1; Loop < 10000000; ++Loop)
{
// Fill the array with three random numbers until you have a match:
array<unsigned, DICE_COUNT> values = { 0 };
while (accumulate(begin(values), end(values), 0) != DESIRED_NUMBER) {
for_each(begin(values), end(values), [&](unsigned &v) {
v = distribution(generator);
//v = rand() % DICE_SIDES; // substitute this to use rand()
});
}
sum[0][values[0]]++;
sum[1][values[1]]++;
sum[2][values[2]]++;
sum_count++;
}
for (int i = 0; i < 10; i++)
printf("Percent of aI==%d:%5.2f bI==%d:%5.2f cI==%d:%5.2f\n",
i, 100.0*sum[0][i] / sum_count,
i, 100.0*sum[1][i] / sum_count,
i, 100.0*sum[2][i] / sum_count);
return 0;
}
/* Results:
Percent of aI==0: 5.48 bI==0: 5.48 cI==0: 5.47
Percent of aI==1: 6.85 bI==1: 6.85 cI==1: 6.85
Percent of aI==2: 8.22 bI==2: 8.19 cI==2: 8.22
Percent of aI==3: 9.60 bI==3: 9.59 cI==3: 9.60
Percent of aI==4:10.97 bI==4:10.96 cI==4:10.99
Percent of aI==5:12.34 bI==5:12.32 cI==5:12.32
Percent of aI==6:13.69 bI==6:13.70 cI==6:13.71
Percent of aI==7:12.31 bI==7:12.34 cI==7:12.30
Percent of aI==8:10.95 bI==8:10.96 cI==8:10.95
Percent of aI==9: 9.60 bI==9: 9.60 cI==9: 9.59
*/
Here's a tutorial how to generate random numbers in C++11: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
The easiest solution is to try it until you find a match:
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <random>
// Don't use "using namespace" in production.
// I only use it to avoid the horizontal scrollbar.
using namespace std;
// Your constants:
static constexpr unsigned DICE_COUNT = 3;
static constexpr unsigned DICE_SIDES = 10;
static constexpr unsigned DESIRED_NUMBER = 15;
int main() {
// Initialize your PRNG:
random_device rd;
mt19937 generator(rd());
uniform_int_distribution<unsigned> distribution(0, DICE_SIDES - 1);
// Fill the array with three random numbers until you have a match:
array<unsigned, DICE_COUNT> values = { 0 };
while (accumulate(begin(values), end(values), 0) != DESIRED_NUMBER) {
for_each(begin(values), end(values), [&](unsigned &v) {
v = distribution(generator);
});
}
// Print the result:
for_each(begin(values), end(values), [&](unsigned &v) {
cout << v << ' ';
});
cout << endl;
return 0;
}
You'll need about nine iterations to have a 50/50 chance that you'll throw a 15:
P(3d10 = 18) ≈ 1/14 (+3 to account for the range shift)
(13/14)^n < 0.5 → n ≈ 9.4
I have two images. One has more green color and another one has better quality (it has right color). How can I improve the first one to have the similar color as the second one.I used the contrast enhancement as
//Contrast enhancement
for (int y = 0; y < rotated.rows; y++)
{
for (int x = 0; x < rotated.cols; x++)
{
for (int c = 0; c < 3; c++)
{
//"* Enter the alpha value [1.0-3.0]: "
//"* Enter the beta value [0-100]: ";
rotated.at<Vec3b>(y, x)[c] =
saturate_cast<uchar>(2.5*(rotated.at<Vec3b>(y, x)[c]) + 30);
}
}
}
It brightens the image. But I like to have similar color as the second one. What are the RGB values to change to have the second image's color.
For contrast enhancement you can use the equivalent of Matlab imadjust. You can find an OpenCV implementation here.
Applying imadjust with default parameters on each separate channel you get:
Here the full code:
#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
void imadjust(const Mat1b& src, Mat1b& dst, int tol = 1, Vec2i in = Vec2i(0, 255), Vec2i out = Vec2i(0, 255))
{
// src : input CV_8UC1 image
// dst : output CV_8UC1 imge
// tol : tolerance, from 0 to 100.
// in : src image bounds
// out : dst image buonds
dst = src.clone();
tol = max(0, min(100, tol));
if (tol > 0)
{
// Compute in and out limits
// Histogram
vector<int> hist(256, 0);
for (int r = 0; r < src.rows; ++r) {
for (int c = 0; c < src.cols; ++c) {
hist[src(r, c)]++;
}
}
// Cumulative histogram
vector<int> cum = hist;
for (int i = 1; i < hist.size(); ++i) {
cum[i] = cum[i - 1] + hist[i];
}
// Compute bounds
int total = src.rows * src.cols;
int low_bound = total * tol / 100;
int upp_bound = total * (100 - tol) / 100;
in[0] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), low_bound));
in[1] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), upp_bound));
}
// Stretching
float scale = float(out[1] - out[0]) / float(in[1] - in[0]);
for (int r = 0; r < dst.rows; ++r)
{
for (int c = 0; c < dst.cols; ++c)
{
int vs = max(src(r, c) - in[0], 0);
int vd = min(int(vs * scale + 0.5f) + out[0], out[1]);
dst(r, c) = saturate_cast<uchar>(vd);
}
}
}
int main()
{
Mat3b img = imread("path_to_image");
vector<Mat1b> planes;
split(img, planes);
for (int i = 0; i < 3; ++i)
{
imadjust(planes[i], planes[i]);
}
Mat3b result;
merge(planes, result);
return 0;
}
I am learning CUDA and still at the very beginner level. I am trying a simple assignment but my code crashes when I run it and I am not sure why. Any help would be appreciated.
EDIT: Crashes on cudaMemcpy and in Image structure, the pixelVal is of type int**. Is that the cause?
Original C++ code:
void Image::reflectImage(bool flag, Image& oldImage)
/*Reflects the Image based on users input*/
{
int rows = oldImage.N;
int cols = oldImage.M;
Image tempImage(oldImage);
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
tempImage.pixelVal[rows - (i + 1)][j] = oldImage.pixelVal[i][j];
}
oldImage = tempImage;
}
My CUDA kernel & code:
#define NTPB 512
__global__ void fliph(int* a, int* b, int r, int c)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i >= r || j >= c)
return;
a[(r - i * c) + j] = b[i * c + j];
}
void Image::reflectImage(bool flag, Image& oldImage)
/*Reflects the Image based on users input*/
{
int rows = oldImage.N;
int cols = oldImage.M;
Image tempImage(oldImage);
if(flag == true) //horizontal reflection
{
//Allocate device memory
int* dpixels;
int* oldPixels;
int n = rows * cols;
cudaMalloc((void**)&dpixels, n * sizeof(int));
cudaMalloc((void**)&oldPixels, n * sizeof(int));
cudaMemcpy(dpixels, tempImage.pixelVal, n * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(oldPixels, oldImage.pixelVal, n * sizeof(int), cudaMemcpyHostToDevice);
int nblks = (n + NTPB - 1) / NTPB;
fliph<<<nblks, NTPB>>>(dpixels, oldPixels, rows, cols);
cudaMemcpy(tempImage.pixelVal, dpixels, n * sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(dpixels);
cudaFree(oldPixels);
}
oldImage = tempImage;
}
You have to create a 2D Grid in order to process the image using 2D indices i and j. In the current case, the kernel is processing only the first row of the image.
To create a 2D indexing mechanism, create a 2D block and 2D grid like this:
const int BLOCK_DIM = 16;
dim3 Block(BLOCK_DIM,BLOCK_DIM);
dim3 Grid;
Grid.x = (cols + Block.x - 1)/Block.x;
Grid.y = (rows + Block.y - 1)/Block.y;
fliph<<<Grid, Block>>>(dpixels, oldPixels, rows, cols);
I've got a vector of samples that form a curve. Let's imagine there are 1000 points in it. If I want to stretch it to fill 1500 points, what is the simplest algorithm that gives decent results? I'm looking for something that is just a few lines of C/C++.
I'll always want to increase the size of the vector, and the new vector can be anywhere from 1.1x to 50x the size of the current vector.
Thanks!
Here's C++ for linear and quadratic interpolation.
interp1( 5.3, a, n ) is a[5] + .3 * (a[6] - a[5]), .3 of the way from a[5] to a[6];
interp1array( a, 1000, b, 1500 ) would stretch a to b.
interp2( 5.3, a, n ) draws a parabola through the 3 nearest points a[4] a[5] a[6]: smoother than interp1 but still fast.
(Splines use 4 nearest points, smoother yet; if you read python, see
basic-spline-interpolation-in-a-few-lines-of-numpy.
// linear, quadratic interpolation in arrays
// from interpol.py denis 2010-07-23 July
#include <stdio.h>
#include <stdlib.h>
// linear interpolate x in an array
// inline
float interp1( float x, float a[], int n )
{
if( x <= 0 ) return a[0];
if( x >= n - 1 ) return a[n-1];
int j = int(x);
return a[j] + (x - j) * ( a[j+1] - a[j] );
}
// linear interpolate array a[] -> array b[]
void interp1array( float a[], int n, float b[], int m )
{
float step = float( n - 1 ) / (m - 1);
for( int j = 0; j < m; j ++ )
{
b[j] = interp1( j*step, a, n );
}
}
//..................................................................
// parabola through 3 points, -1 < x < 1
float parabola( float x, float f_1, float f0, float f1 )
{
if( x <= -1 ) return f_1;
if( x >= 1 ) return f1;
float l = f0 - x * (f_1 - f0);
float r = f0 + x * (f1 - f0);
return (l + r + x * (r - l)) / 2;
}
// quadratic interpolate x in an array
float interp2( float x, float a[], int n )
{
if( x <= .5 || x >= n - 1.5 )
return interp1( x, a, n );
int j = int( x + .5 );
float t = 2 * (x - j); // -1 .. 1
return parabola( t, (a[j-1] + a[j]) / 2, a[j], (a[j] + a[j+1]) / 2 );
}
// quadratic interpolate array a[] -> array b[]
void interp2array( float a[], int n, float b[], int m )
{
float step = float( n - 1 ) / (m - 1);
for( int j = 0; j < m; j ++ ){
b[j] = interp2( j*step, a, n );
}
}
int main( int argc, char* argv[] )
{
// a.out [n m] --
int n = 10, m = 100;
int *ns[] = { &n, &m, 0 },
**np = ns;
char* arg;
for( argv ++; (arg = *argv) && *np; argv ++, np ++ )
**np = atoi( arg );
printf( "n: %d m: %d\n", n, m );
float a[n], b[m];
for( int j = 0; j < n; j ++ ){
a[j] = j * j;
}
interp2array( a, n, b, m ); // a[] -> b[]
for( int j = 0; j < m; j ++ ){
printf( "%.1f ", b[j] );
}
printf( "\n" );
}
what is the simplest algorithm that gives decent results?
Catmull-Rom splines. (if you want a smooth curve)
http://www.mvps.org/directx/articles/catmull/
http://en.wikipedia.org/wiki/Cubic_Hermite_spline
For each new item calculate fractional position in old array, use use fractional part (f - floor(f)) as interpolation factor, and "integer" (i.e. floor(f)) part to find nearest elements.
That is assuming that you're operating on data that can be mathematically interpolated (floats). If data cannot be interpolated (strings), then the only solution is to use nearest available element of old array.
You'll need some tweaking if points in array aren't evenly distributed.
Simplest option I can think of is just a fn that expands the array based on mean averages, so:
x,y,z
becomes
x, avg(x,y), y, avg (y,z), z
If you need more data points, just run it multiple times on the vector.