void convertToFloatImage(CByteImage &byteImage, CFloatImage &floatImage) { CShape sh = byteImage.Shape(); //printf("%d\n", floatImage.Shape().nBands); //printf("%d\n", byteImage.Shape().nBands); assert(floatImage.Shape().nBands == min(byteImage.Shape().nBands, 3)); for (int y=0; y<sh.height; y++) { for (int x=0; x<sh.width; x++) { for (int c=0; c<min(3,sh.nBands); c++) { float value = byteImage.Pixel(x,y,c) / 255.0f; if (value < floatImage.MinVal()) { value = floatImage.MinVal(); } else if (value > floatImage.MaxVal()) { value = floatImage.MaxVal(); } // We have to flip the image and reverse the color // channels to get it to come out right. How silly! floatImage.Pixel(x,sh.height-y-1,min(3,sh.nBands)-c-1) = value; } } } }
extern void ForwardWarp(CImageOf<T>& src, CImageOf<T>& dst, CFloatImage& disp, float d_scale, bool line_interpolate, float disp_gap) { // Warps src into dst using disparities disp. // Each disparity is scaled by d_scale // Note that "empty" pixels are left at their original value CShape sh = src.Shape(); int w = sh.width, h = sh.height, n_bands = sh.nBands; float round_offset = (typeid(T) == typeid(float)) ? 0.0f : 0.5f; if (! sh.SameIgnoringNBands(disp.Shape())) throw CError("ForwardWarp: disparity image has wrong size"); if (sh != dst.Shape()) dst.ReAllocate(sh); // Optional clipping (if necessary) CFloatImage flt; T minVal = dst.MinVal(); T maxVal = dst.MaxVal(); if (minVal <= flt.MinVal() && maxVal >= flt.MaxVal()) minVal = maxVal = 0; for (int y = 0; y < h; y++) { // determine correct warping direction int xstart = (d_scale>0 ? 0 : w-1); int xend = (d_scale>0 ? w : -1 ); int xincr = (d_scale>0 ? 1 : -1 ); float *dp = &disp.Pixel(0, y, 0); T *ps = &src .Pixel(0, y, 0); T *pd = &dst .Pixel(0, y, 0); for (int x = xstart; x != xend; x += xincr) { // determine if a line should be drawn int x2 = x + xincr; float d_diff = fabs(dp[x] - dp[x2]); bool draw_line = line_interpolate && (x2 != xend) && (d_diff < disp_gap); // scaled disparity: float d = d_scale * dp[x]; // line drawing if (draw_line) { float d2 = d_scale * dp[x2]; if (xincr > 0) draw_intensity_line(&ps[x * n_bands], &ps[x2 * n_bands], pd, x - d, x2 - d2, w, n_bands, round_offset, minVal, maxVal); else draw_intensity_line(&ps[x2 * n_bands], &ps[x * n_bands], pd, x2 - d, x - d2, w, n_bands, round_offset, minVal, maxVal); continue; } // splatting int xx = x - ROUND(d); if (xx >= 0 && xx < w) memcpy(&pd[xx * n_bands], &ps[x * n_bands], n_bands*sizeof(T)); } } }
extern void InverseWarp(CImageOf<T>& src, CImageOf<T>& dst, CFloatImage& disp, float d_scale, float disp_gap, int order) { // Warps src into dst using disparities disp. // Each disparity is scaled by d_scale // Note that "empty" pixels are left at their original value CShape sh = src.Shape(); int w = sh.width, h = sh.height, n_bands = sh.nBands; int n = w * n_bands; if (! sh.SameIgnoringNBands(disp.Shape())) throw CError("InverseWarp: disparity image has wrong size"); if (sh != dst.Shape()) dst.ReAllocate(sh); // Optional forward warped depth map if checking for visibility CFloatImage fwd, fwd_tmp; if (disp_gap > 0.0f) { ScaleAndOffset(disp, fwd_tmp, d_scale, 0.0f); fwd.ReAllocate(disp.Shape()); fwd.FillPixels(-9999.0f); ForwardWarp(fwd_tmp, fwd, disp, d_scale, true, disp_gap); } // Allocate line buffers std::vector<float> src_buf, dst_buf, dsp_buf; src_buf.resize(n); dst_buf.resize(n); dsp_buf.resize(n); CFloatImage fimg; // dummy, used for MinVal(), MaxVal() for (int y = 0; y < h; y++) { // Set up (copy) the line buffers ScaleAndOffsetLine(&src .Pixel(0, y, 0), &src_buf[0], n, 1.0f, 0.0f, fimg.MinVal(), fimg.MaxVal()); ScaleAndOffsetLine(&disp.Pixel(0, y, 0), &dsp_buf[0], w, d_scale, 0.0f, 0.0f, 0.0f); ScaleAndOffsetLine(&dst .Pixel(0, y, 0), &dst_buf[0], n, 1.0f, 0.0f, fimg.MinVal(), fimg.MaxVal()); // Forward warp the depth map float *fwd_buf = (disp_gap > 0.0f) ? &fwd.Pixel(0, y, 0) : 0; // Process (warp) the line InverseWarpLine(&src_buf[0], &dst_buf[0], &dsp_buf[0], w, n_bands, order, fwd_buf, disp_gap); // Convert back to native type T minVal = dst.MinVal(); T maxVal = dst.MaxVal(); float offset = (typeid(T) == typeid(float)) ? 0.0f : 0.5; // rounding if (minVal <= fimg.MinVal() && maxVal >= fimg.MaxVal()) minVal = maxVal = 0; ScaleAndOffsetLine(&dst_buf[0], &dst.Pixel(0, y, 0), n, 1.0f, offset, minVal, maxVal); } }