satdump/src-testing/kernel.cl
2022-04-19 13:44:11 +02:00

98 lines
No EOL
3.4 KiB
Common Lisp

inline double SQ(const double x) { return x * x; }
inline void VizGeorefSpline2DBase_func4(double *res, const double *pxy,
const double *xr, const double *yr) {
double dist0 = SQ(xr[0] - pxy[0]) + SQ(yr[0] - pxy[1]);
res[0] = dist0 != 0.0 ? dist0 * log(dist0) : 0.0;
double dist1 = SQ(xr[1] - pxy[0]) + SQ(yr[1] - pxy[1]);
res[1] = dist1 != 0.0 ? dist1 * log(dist1) : 0.0;
double dist2 = SQ(xr[2] - pxy[0]) + SQ(yr[2] - pxy[1]);
res[2] = dist2 != 0.0 ? dist2 * log(dist2) : 0.0;
double dist3 = SQ(xr[3] - pxy[0]) + SQ(yr[3] - pxy[1]);
res[3] = dist3 != 0.0 ? dist3 * log(dist3) : 0.0;
}
inline double VizGeorefSpline2DBase_func(const double x1, const double y1,
const double x2, const double y2) {
const double dist = SQ(x2 - x1) + SQ(y2 - y1);
return dist != 0.0 ? dist * log(dist) : 0.0;
}
void kernel warp_image_thin_plate_spline(
global ushort *map_image, global ushort *img, global int *tps_no_points,
global double *tps_x, global double *tps_y, global double *tps_coef_1,
global double *tps_coef_2, global double *tps_xmean,
global double *tps_ymean, global int *img_settings) {
int id = get_global_id(0);
int nthreads = get_global_size(0);
int map_img_width = img_settings[0];
int map_img_height = img_settings[1];
int img_width = img_settings[2];
int img_height = img_settings[3];
int img_channels = img_settings[4];
size_t n =
(img_settings[8] - img_settings[7]) * (img_settings[6] - img_settings[5]);
size_t ratio = (n / nthreads); // number of elements for each thread
size_t start = ratio * id;
size_t stop = ratio * (id + 1);
// Init TPS
double xx, yy;
double vars[2];
double *coef[2] = {tps_coef_1, tps_coef_2};
int _nof_points = *tps_no_points;
int _nof_vars = 2;
double x_mean = *tps_xmean;
double y_mean = *tps_ymean;
for (size_t xy_ptr = start; xy_ptr < stop; xy_ptr++) {
int x = (xy_ptr % (img_settings[8] - img_settings[7])) + img_settings[7];
int y = (xy_ptr / (img_settings[8] - img_settings[7])) + img_settings[5];
// Scale to the map
double lat = -((double)y / (double)map_img_height) * 180 + 90;
double lon = ((double)x / (double)map_img_width) * 360 - 180;
// Perform TPS
{
const double Pxy[2] = {lon - x_mean, lat - y_mean};
for (int v = 0; v < _nof_vars; v++)
vars[v] = coef[v][0] + coef[v][1] * Pxy[0] + coef[v][2] * Pxy[1];
int r = 0; // Used after for.
for (; r < (_nof_points & (~3)); r += 4) {
double dfTmp[4] = {};
VizGeorefSpline2DBase_func4(dfTmp, Pxy, &tps_x[r], &tps_y[r]);
for (int v = 0; v < _nof_vars; v++)
vars[v] += coef[v][r + 3] * dfTmp[0] + coef[v][r + 3 + 1] * dfTmp[1] +
coef[v][r + 3 + 2] * dfTmp[2] +
coef[v][r + 3 + 3] * dfTmp[3];
}
for (; r < _nof_points; r++) {
const double tmp =
VizGeorefSpline2DBase_func(Pxy[0], Pxy[1], tps_x[r], tps_y[r]);
for (int v = 0; v < _nof_vars; v++)
vars[v] += coef[v][r + 3] * tmp;
}
xx = vars[0];
yy = vars[1];
}
if (xx < 0 || yy < 0)
continue;
if ((int)xx > img_width - 1 || (int)yy > img_height - 1)
continue;
for (int c = 0; c < img_channels; c++)
map_image[(map_img_width * map_img_height) * c + y * map_img_width + x] =
img[(img_width * img_height) * c + (int)yy * img_width + (int)xx];
}
}