void RaspiVoice::initTestImage()
{
	if (verbose)
	{
		if (use_bw_test_image)
		{
			std::cout << "Using B/W test image" << std::endl;
		}
		else
		{
			std::cout << "Using grayscale test image" << std::endl;
		}
	}

	// Set hard-coded image
	for (int j = 0; j < columns; j++)
	{
		for (int i = 0; i < rows; i++)
		{
			if (use_bw_test_image)
			{
				if (P_bw[rows - i - 1][j] != '#')
				{
					(*image)[IDX2D(i, j)] = 1.0; // white;
				}
				else
				{
					(*image)[IDX2D(i, j)] = 0.0; // black;
				}
			}
			else if (P_grayscale[i][j] > 'a')
			{
				(*image)[IDX2D(rows - i - 1, j)] = pow(10.0, (P_grayscale[i][j] - 'a' - 15) / 10.0);   // 2dB steps
			}
			else
			{
				(*image)[IDX2D(rows - i - 1, j)] = 0.0;
			}
		}
	}
}
Exemple #2
0
static int
bilinear_deriv_x(const void * state, const double xarr[],
                 const double yarr[], const double zarr[],
                 size_t xsize, size_t ysize, double x, double y,
                 gsl_interp_accel * xa, gsl_interp_accel * ya, double * z_p)
{
  double xmin, xmax, ymin, ymax, zminmin, zminmax, zmaxmin, zmaxmax;
  double dx, dy;
  double dt, u;
  size_t xi, yi;

  if (xa != NULL)
    xi = gsl_interp_accel_find(xa, xarr, xsize, x);
  else
    xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);

  if (ya != NULL)
    yi = gsl_interp_accel_find(ya, yarr, ysize, y);
  else
    yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);

  xmin = xarr[xi];
  xmax = xarr[xi + 1];
  ymin = yarr[yi];
  ymax = yarr[yi + 1];
  zminmin = zarr[IDX2D(xi, yi, xsize, ysize)];
  zminmax = zarr[IDX2D(xi, yi + 1, xsize, ysize)];
  zmaxmin = zarr[IDX2D(xi + 1, yi, xsize, ysize)];
  zmaxmax = zarr[IDX2D(xi + 1, yi + 1, xsize, ysize)];
  dx = xmax - xmin;
  dy = ymax - ymin;
  dt = 1./dx; /* partial t / partial x */
  u = (y - ymin)/dy;
  *z_p = dt*(-(1.-u)*zminmin + (1.-u)*zmaxmin - u*zminmax + u*zmaxmax);

  return GSL_SUCCESS;
}
Exemple #3
0
static int
bilinear_eval(const void * state, const double xarr[], const double yarr[],
              const double zarr[], size_t xsize, size_t ysize,
              double x, double y, gsl_interp_accel * xa,
              gsl_interp_accel * ya, double * z)
{
  double xmin, xmax, ymin, ymax, zminmin, zminmax, zmaxmin, zmaxmax;
  double dx, dy;
  double t, u;
  size_t xi, yi;

  if (xa != NULL)
    xi = gsl_interp_accel_find(xa, xarr, xsize, x);
  else
    xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);

  if (ya != NULL)
    yi = gsl_interp_accel_find(ya, yarr, ysize, y);
  else
    yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);

  xmin = xarr[xi];
  xmax = xarr[xi + 1];
  ymin = yarr[yi];
  ymax = yarr[yi + 1];
  zminmin = zarr[IDX2D(xi, yi, xsize, ysize)];
  zminmax = zarr[IDX2D(xi, yi + 1, xsize, ysize)];
  zmaxmin = zarr[IDX2D(xi + 1, yi, xsize, ysize)];
  zmaxmax = zarr[IDX2D(xi + 1, yi + 1, xsize, ysize)];
  dx = xmax - xmin;
  dy = ymax - ymin;
  t = (x - xmin)/dx;
  u = (y - ymin)/dy;
  *z = (1.-t)*(1.-u)*zminmin + t*(1.-u)*zmaxmin + (1.-t)*u*zminmax + t*u*zmaxmax;

  return GSL_SUCCESS;
}
Exemple #4
0
static int
bicubic_init(void * vstate, const double xa[], const double ya[],
             const double za[], size_t xsize, size_t ysize)
{
  bicubic_state_t *state = (bicubic_state_t *) vstate;

  gsl_interp_accel *acc = gsl_interp_accel_alloc();
  gsl_spline *spline;
  gsl_vector *x;
  gsl_vector *y;
  size_t i, j;

  x = gsl_vector_alloc(xsize);
  y = gsl_vector_alloc(xsize);
  spline = gsl_spline_alloc(gsl_interp_cspline, xsize);
  for (j = 0; j <= ysize - 1; j++)
    {
      for (i = 0; i <= xsize - 1; i++)
        {
          gsl_vector_set(x, i, xa[i]);
          gsl_vector_set(y, i, za[IDX2D(i, j, state)]);
        }
      gsl_spline_init(spline, x->data, y->data, xsize);
      for (i = 0; i <= xsize - 1; i++)
        {
          state->zx[IDX2D(i, j, state)] = gsl_spline_eval_deriv(spline, xa[i], acc);
        }
    }
  gsl_vector_free(x);
  gsl_vector_free(y);
  gsl_spline_free(spline);
  gsl_interp_accel_reset(acc);

  x = gsl_vector_alloc(ysize);
  y = gsl_vector_alloc(ysize);
  spline = gsl_spline_alloc(gsl_interp_cspline, ysize);
  for (i = 0; i <= xsize - 1; i++)
    {
      for (j = 0; j <= ysize - 1; j++)
        {
          gsl_vector_set(x, j, ya[j]);
          gsl_vector_set(y, j, za[IDX2D(i, j, state)]);
        }
      gsl_spline_init(spline, x->data, y->data, ysize);
      for (j = 0; j <= ysize - 1; j++)
        {
          state->zy[IDX2D(i, j, state)] = gsl_spline_eval_deriv(spline, ya[j], acc);
        }
    }
  gsl_vector_free(x);
  gsl_vector_free(y);
  gsl_spline_free(spline);
  gsl_interp_accel_reset(acc);

  x = gsl_vector_alloc(xsize);
  y = gsl_vector_alloc(xsize);
  spline = gsl_spline_alloc(gsl_interp_cspline, xsize);
  for (j = 0; j <= ysize - 1; j++)
    {
      for (i = 0; i <= xsize - 1; i++)
        {
          gsl_vector_set(x, i, xa[i]);
          gsl_vector_set(y, i, state->zy[IDX2D(i, j, state)]);
        }
      gsl_spline_init(spline, x->data, y->data, xsize);
      for (i = 0; i <= xsize - 1; i++)
        {
          state->zxy[IDX2D(i, j, state)] = gsl_spline_eval_deriv(spline, xa[i], acc);
        }
    }
  gsl_vector_free(x);
  gsl_vector_free(y);
  gsl_spline_free(spline);
  gsl_interp_accel_free(acc);

  return GSL_SUCCESS;
} /* bicubic_init() */
Exemple #5
0
static int
bicubic_deriv_yy(const void * vstate, const double xarr[], const double yarr[],
                 const double zarr[], size_t xsize, size_t ysize,
                 double x, double y,
                 gsl_interp_accel * xa, gsl_interp_accel * ya, double * z_pp)
{
  bicubic_state_t *state = (bicubic_state_t *) vstate;

  double xmin, xmax, ymin, ymax;
  double zminmin, zminmax, zmaxmin, zmaxmax;
  double zxminmin, zxminmax, zxmaxmin, zxmaxmax;
  double zyminmin, zyminmax, zymaxmin, zymaxmax;
  double zxyminmin, zxyminmax, zxymaxmin, zxymaxmax;

  double dx, dy; /* size of the grid cell */
  double dt, du;

  /*
   * t and u are the positions within the grid cell at which we are computing
   * the interpolation, in units of grid cell size
   */
  double t, u;
  double t0, t1, t2, t3, u0, u1;
  double v;
  size_t xi, yi;

  /* first compute the indices into the data arrays where we are interpolating */
  if (xa != NULL)
    xi = gsl_interp_accel_find(xa, xarr, xsize, x);
  else
    xi = gsl_interp_bsearch(xarr, x, 0, xsize - 1);

  if (ya != NULL)
    yi = gsl_interp_accel_find(ya, yarr, ysize, y);
  else
    yi = gsl_interp_bsearch(yarr, y, 0, ysize - 1);

  /* find the minimum and maximum values on the grid cell in each dimension */
  xmin = xarr[xi];
  xmax = xarr[xi + 1];
  ymin = yarr[yi];
  ymax = yarr[yi + 1];
  zminmin = zarr[IDX2D(xi, yi, state)];
  zminmax = zarr[IDX2D(xi, yi + 1, state)];
  zmaxmin = zarr[IDX2D(xi + 1, yi, state)];
  zmaxmax = zarr[IDX2D(xi + 1, yi + 1, state)];

  /* get the width and height of the grid cell */
  dx = xmax - xmin;
  dy = ymax - ymin;
  t = (x - xmin)/dx;
  u = (y - ymin)/dy;
  dt = 1./dx; /* partial t / partial x */
  du = 1./dy; /* partial u / partial y */

  zxminmin = state->zx[IDX2D(xi, yi, state)]/dt;
  zxminmax = state->zx[IDX2D(xi, yi + 1, state)]/dt;
  zxmaxmin = state->zx[IDX2D(xi + 1, yi, state)]/dt;
  zxmaxmax = state->zx[IDX2D(xi + 1, yi + 1, state)]/dt;
  zyminmin = state->zy[IDX2D(xi, yi, state)]/du;
  zyminmax = state->zy[IDX2D(xi, yi + 1, state)]/du;
  zymaxmin = state->zy[IDX2D(xi + 1, yi, state)]/du;
  zymaxmax = state->zy[IDX2D(xi + 1, yi + 1, state)]/du;
  zxyminmin = state->zxy[IDX2D(xi, yi, state)]/(dt*du);
  zxyminmax = state->zxy[IDX2D(xi, yi + 1, state)]/(dt*du);
  zxymaxmin = state->zxy[IDX2D(xi + 1, yi, state)]/(dt*du);
  zxymaxmax = state->zxy[IDX2D(xi + 1, yi + 1, state)]/(dt*du);

  t0 = 1;
  t1 = t;
  t2 = t*t;
  t3 = t*t2;
  u0 = 1;
  u1 = u;

  *z_pp = 0;
  v = -3*zminmin + 3*zminmax - 2*zyminmin - zyminmax;
  *z_pp += 2*v*t0*u0;
  v = 2*zminmin-2*zminmax + zyminmin + zyminmax;
  *z_pp += 6*v*t0*u1;
  v = -3*zxminmin + 3*zxminmax - 2*zxyminmin - zxyminmax;
  *z_pp += 2*v*t1*u0;
  v = 2*zxminmin - 2*zxminmax + zxyminmin + zxyminmax;
  *z_pp += 6*v*t1*u1;
  v = 9*zminmin - 9*zmaxmin + 9*zmaxmax - 9*zminmax + 6*zxminmin + 3*zxmaxmin - 3*zxmaxmax - 6*zxminmax + 6*zyminmin - 6*zymaxmin - 3*zymaxmax + 3*zyminmax + 4*zxyminmin + 2*zxymaxmin + zxymaxmax + 2*zxyminmax;
  *z_pp += 2*v*t2*u0;
  v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 4*zxminmin - 2*zxmaxmin + 2*zxmaxmax + 4*zxminmax - 3*zyminmin + 3*zymaxmin + 3*zymaxmax - 3*zyminmax - 2*zxyminmin - zxymaxmin - zxymaxmax - 2*zxyminmax;
  *z_pp += 6*v*t2*u1;
  v = -6*zminmin + 6*zmaxmin - 6*zmaxmax + 6*zminmax - 3*zxminmin - 3*zxmaxmin + 3*zxmaxmax + 3*zxminmax - 4*zyminmin + 4*zymaxmin + 2*zymaxmax - 2*zyminmax - 2*zxyminmin - 2*zxymaxmin - zxymaxmax - zxyminmax;
  *z_pp += 2*v*t3*u0;
  v = 4*zminmin - 4*zmaxmin + 4*zmaxmax - 4*zminmax + 2*zxminmin + 2*zxmaxmin - 2*zxmaxmax - 2*zxminmax + 2*zyminmin - 2*zymaxmin - 2*zymaxmax + 2*zyminmax + zxyminmin + zxymaxmin + zxymaxmax + zxyminmax;
  *z_pp += 6*v*t3*u1;
  *z_pp *= du*du;

  return GSL_SUCCESS;
}
void RaspiVoice::processImage(cv::Mat rawImage)
{
	cv::Mat processedImage = rawImage;

	if (verbose)
	{
		printtime("ProcessImage start");
	}

	if ((image_source > 0) || (opt.input_filename != ""))
	{
		if (opt.foveal_mapping)
		{
			cv::Matx33f cameraMatrix(100, 0, processedImage.cols / 2, 0, 100, processedImage.rows / 2, 0, 0, 1);
			cv::Matx41f distCoeffs(5.0, 5.0, 0, 0);
			cv::Mat processedImage2;
			cv::undistort(processedImage, processedImage2, cameraMatrix, distCoeffs);
			float clipzoom = 1.8; //horizontal zoom to remove blinders, decreases resolution if > 1.0
			cv::Rect roi(processedImage.cols / 2 - columns / 2 / clipzoom, processedImage.rows / 2 - rows / 2, columns / clipzoom, rows);
			processedImage = processedImage2(roi);
		}

		if (opt.zoom > 1.0)
		{
			int w = processedImage.cols;
			int h = processedImage.rows;
			float z = opt.zoom;
			cv::Rect roi((w / 2.0) - w / (2.0*z), (h / 2.0) - h / (2.0*z), w/z, h/z);
			processedImage = processedImage(roi);
		}

		//Bring to size needed by ImageToSoundscape:
		if (processedImage.rows != rows || processedImage.cols != columns)
		{
			cv::resize(processedImage, processedImage, cv::Size(columns, rows));
		}

		if ((opt.blinders > 0) && (opt.blinders < columns/2))
		{
			processedImage(cv::Rect(0, 0, opt.blinders, rows - 1)).setTo(0);
			processedImage(cv::Rect(columns - 1 - opt.blinders, 0, opt.blinders, rows - 1)).setTo(0);
		}

		if (opt.contrast != 0.0)
		{
   			float avg = 0.0;    
   			for (int y = 0; y < processedImage.rows; y++)
   			{
      				for (int x = 0; x < processedImage.cols; x++)
      				{
         			avg += processedImage.at<uchar>(y, x);
      				}
   			}
   			avg = avg / (processedImage.rows * processedImage.cols);
   			for (int y = 0; y < processedImage.rows; y++)
   			{
      				for (int x = 0; x < processedImage.cols; x++)
      				{
         				int mVal = processedImage.at<uchar>(y, x);
         				processedImage.at<uchar>(y, x) = cv::saturate_cast<uchar>(mVal + opt.contrast*(mVal - avg));
      				}
   			}
		}
		if (opt.threshold > 0)
		{
			if (opt.threshold < 255)
			{
				cv::threshold(processedImage, processedImage, opt.threshold, 255, cv::THRESH_BINARY);
			}
			else
			{
				//Auto threshold:
				cv::threshold(processedImage, processedImage, 127, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
			}
		}

		if (opt.negative_image)
		{
			cv::Mat sub_mat = cv::Mat::ones(processedImage.size(), processedImage.type()) * 255;
			cv::subtract(sub_mat, processedImage, processedImage);
		}

		if (opt.edge_detection_opacity > 0.0)
		{
			cv::Mat blurImage;
			cv::Mat edgesImage;
			int ratio = 3;
			int kernel_size = 3;
			int lowThreshold = opt.edge_detection_threshold;
			if (lowThreshold <= 0)
			{
				lowThreshold = 127;
			}
			cv::blur(processedImage, blurImage, cv::Size(3, 3));
			cv::Canny(blurImage, edgesImage, lowThreshold, lowThreshold*ratio, kernel_size);

			double alpha = opt.edge_detection_opacity;
			if (alpha > 1.0)
			{
				alpha = 1.0;
			}
			double beta = (1.0 - alpha);
			cv::addWeighted(edgesImage, alpha, processedImage, beta, 0.0, processedImage);
		}

		if ((opt.flip >= 1) && (opt.flip <= 3))
		{
			int flipCode;
			if (opt.flip == 1) //h
			{
				flipCode = 1;
			}
			else if (opt.flip == 2) //v
			{
				flipCode = 0;
			}
			else if (opt.flip == 3) //h+v
			{
				flipCode = -1;
			}

			cv::flip(processedImage, processedImage, flipCode);
		}

		if (preview)
		{
			//Screen views
			//imwrite("raspivoice_capture_raw.jpg", rawImage);
			//imwrite("raspivoice_capture_scaled_gray.jpg", processedImage);
			cv::imshow("RaspiVoice Preview", processedImage);

			cv::waitKey(200);
		}

		/* Set live camera image */
		for (int j = 0; j < columns; j++)
		{
			for (int i = 0; i < rows; i++)
			{
				int mVal = processedImage.at<uchar>(rows - 1 - i, j) / 16;
				if (mVal == 0)
				{
					(*image)[IDX2D(i, j)] = 0;
				}
				else
				{
					(*image)[IDX2D(i, j)] = pow(10.0, (mVal - 15) / 10.0);   // 2dB steps
				}
			}
		}
	}

}
void ImageToSoundscapeConverter::processStereo(const std::vector<float> &image)
{
	float tau1 = 0.5 / omega[rows - 1];
	float tau2 = 0.25 * tau1*tau1;
	float yl = 0.0, yr = 0.0;
	float zl = 0.0, zr = 0.0;
	for (int sample = 0; sample < sampleCount; sample++)
	{
		float q, q2, f1, f2;
		if (use_bspline)
		{
			q = 1.0 * (sample % samplesPerColumn) / (samplesPerColumn - 1);
			q2 = 0.5 * q * q;
			f1 = (q2 - q + 0.5);
			f2 = (0.5 + q - q*q);
		}

		int j = sample / samplesPerColumn;
		if (j > columns - 1)
		{
			j = columns - 1;
		}

		float r = 1.0 * sample / (sampleCount - 1);  // Binaural attenuation/delay parameter
		float theta = (r - 0.5) * TwoPi / 3;
		float x = 0.5 * acoustical_size_of_head_m * (theta + sin(theta));
		float tl = sample * timePerSample_s;
		float tr = tl;
		if (use_delay)
		{
			tr += x / speed_of_sound_m_s;  // Time delay model
		}
		x = fabs(x);
		float sl = 0.0, sr = 0.0;

		const float *im1, *im2, *im3;
		if (j > 0)
		{
			im1 = &image[IDX2D(0, j - 1)];
		}
		im2 = &image[IDX2D(0, j)];
		if (j < columns - 1)
		{
			im3 = &image[IDX2D(0, j + 1)];
		}

		for (int i = 0; i < rows; i++)
		{
			float a;
			if (use_bspline)
			{
				if (j == 0)
				{
					a = (1.0 - q2)*im2[i] + q2*im3[i];
				}
				else if (j == columns - 1)
				{
					a = f1*im1[i] + f2*im2[i];
				}
				else
				{
					a = f1*im1[i] + f2*im2[i] + q2*im3[i];
				}
			}
			else
			{
				a = im2[i];
			}

			sl += a * waveformCacheLeftChannel[(sample * rows) + i];
			sr += a * waveformCacheRightChannel[(sample * rows) + i];
		}

		if (sample < sampleCount / (5 * columns))
		{
			sl = (2.0*rnd() - 1.0) / scale;   // Left "click"
		}

		if (tl < 0.0)
		{
			sl = 0.0;
		}

		if (tr < 0.0)
		{
			sr = 0.0;
		}

		float ypl = yl;
		yl = tau1 / timePerSample_s + tau2 / (timePerSample_s*timePerSample_s);
		yl = (sl + yl * ypl + tau2 / timePerSample_s * zl) / (1.0 + yl);
		zl = (yl - ypl) / timePerSample_s;
		float ypr = yr;
		yr = tau1 / timePerSample_s + tau2 / (timePerSample_s*timePerSample_s);
		yr = (sr + yr * ypr + tau2 / timePerSample_s * zr) / (1.0 + yr);
		zr = (yr - ypr) / timePerSample_s;

		uint16_t* sampleBuffer = audioData.Data();
			
		int32_t l = 0.5 + scale * 32768.0 * yl;
		if (l > 32767)
		{
			l = 32767;
		} else if (l < -32768)
		{
			l = -32768;
		}
		sampleBuffer[2 * sample] = (uint16_t)l;

		l = 0.5 + scale * 32768.0 * yr;
		if (l > 32767)
		{
			l = 32767;
		}
		else if (l < -32768)
		{
			l = -32768;
		}
		sampleBuffer[2 * sample + 1] = (uint16_t)l;
	}
}