// convert float disparity image into a color image using jet colormap void float2color(CFloatImage fimg, CByteImage &img, float dmin, float dmax) { CShape sh = fimg.Shape(); int width = sh.width, height = sh.height; sh.nBands = 3; img.ReAllocate(sh); float scale = 1.0 / (dmax - dmin); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float f = fimg.Pixel(x, y, 0); int r = 0; int g = 0; int b = 0; if (f != INFINITY) { float val = scale * (f - dmin); jet(val, r, g, b); } img.Pixel(x, y, 0) = b; img.Pixel(x, y, 1) = g; img.Pixel(x, y, 2) = r; } } }
void getDisparities(MRF *mrf, int width, int height, CByteImage &disp) { CShape sh(width, height, 1); disp.ReAllocate(sh); int n = 0; for (int y = 0; y < height; y++) { uchar *row = &disp.Pixel(0, y, 0); for (int x = 0; x < width; x++) { row[x] = mrf->getLabel(n++); } } }
void MotionToColor(CFloatImage motim, CByteImage &colim, float maxmotion) { CShape sh = motim.Shape(); int width = sh.width, height = sh.height; colim.ReAllocate(CShape(width, height, 3)); int x, y; // determine motion range: float maxx = -999, maxy = -999; float minx = 999, miny = 999; float maxrad = -1; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { float fx = motim.Pixel(x, y, 0); float fy = motim.Pixel(x, y, 1); if (unknown_flow(fx, fy)) continue; maxx = __max(maxx, fx); maxy = __max(maxy, fy); minx = __min(minx, fx); miny = __min(miny, fy); float rad = sqrt(fx * fx + fy * fy); maxrad = __max(maxrad, rad); } } printf("max motion: %.4f motion range: u = %.3f .. %.3f; v = %.3f .. %.3f\n", maxrad, minx, maxx, miny, maxy); if (maxmotion > 0) // i.e., specified on commandline maxrad = maxmotion; if (maxrad == 0) // if flow == 0 everywhere maxrad = 1; if (verbose) fprintf(stderr, "normalizing by %g\n", maxrad); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { float fx = motim.Pixel(x, y, 0); float fy = motim.Pixel(x, y, 1); uchar *pix = &colim.Pixel(x, y, 0); if (unknown_flow(fx, fy)) { pix[0] = pix[1] = pix[2] = 0; } else { computeColor(fx/maxrad, fy/maxrad, pix); } } } }
void WTA(MRF::CostVal *dsi, int width, int height, int nD, CByteImage &disp) { CShape sh(width, height, 1); disp.ReAllocate(sh); int n = 0; for (int y = 0; y < height; y++) { uchar *row = &disp.Pixel(0, y, 0); for (int x = 0; x < width; x++) { int minval = dsi[n++]; // dsi(x,y,0) int mind = 0; for (int d = 1; d < nD; d++) { int val = dsi[n++]; // dsi(x,y,d) if (val < minval) { minval = val; mind = d; } } row[x] = mind; } } }
void makeNonoccMask(CFloatImage disp0, CFloatImage disp0y, CFloatImage disp1, int dir, float thresh, CByteImage &mask) { CShape sh = disp0.Shape(); int width = sh.width, height = sh.height; if (sh != disp1.Shape()) throw CError("shapes differ"); int ydisps = (sh == disp0y.Shape()); mask.ReAllocate(sh); mask.ClearPixels(); int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { float dx = disp0.Pixel(x, y, 0); float dy = (ydisps ? disp0y.Pixel(x, y, 0) : 0.0); if (dx == INFINITY) // unknown continue; mask.Pixel(x, y, 0) = 128; // occluded // find nonocc int x1 = (int)round(x + dir * dx); int y1 = (int)round(y + dy); if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) continue; float dx1 = disp1.Pixel(x1, y1, 0); float diff = dx - dx1; if (fabs(diff) > thresh) continue; // fails cross checking -- occluded mask.Pixel(x, y, 0) = 255; // cross-checking OK } } }
void ReadFileTGA(CByteImage& img, const char* filename) { // Open the file and read the header FILE *stream = fopen(filename, "rb"); if (stream == 0) throw CError("ReadFileTGA: could not open %s", filename); CTargaHead h; if (fread(&h, sizeof(CTargaHead), 1, stream) != 1) throw CError("ReadFileTGA(%s): file is too short", filename); // Throw away the image descriptor if (h.idLength > 0) { char* tmp = new char[h.idLength]; int nread = fread(tmp, sizeof(uchar), h.idLength, stream); delete tmp; // throw away this data if (nread != h.idLength) throw CError("ReadFileTGA(%s): file is too short", filename); } bool isRun = (h.imageType & 8) != 0; bool reverseRows = (h.descriptor & TargaScreenOrigin) != 0; int fileBytes = (h.pixelSize + 7) / 8; // Read the colormap uchar colormap[TargaCMapSize][TargaCMapBands]; int cMapSize = 0; bool grayRamp = false; if (h.colorMapType == 1) { cMapSize = (h.cMapLength[1] << 8) + h.cMapLength[0]; if (h.cMapBits != 24) throw CError("ReadFileTGA(%s): only 24-bit colormap currently supported", filename); int l = fileBytes * cMapSize; if (l > TargaCMapSize * TargaCMapBands) throw CError("ReadFileTGA(%s): colormap is too large", filename); if (fread(colormap, sizeof(uchar), l, stream) != l) throw CError("ReadFileTGA(%s): could not read the colormap", filename); // Check if it's just a standard gray ramp int i; for (i = 0; i < cMapSize; i++) { for (int j = 0; j < TargaCMapBands; j++) if (colormap[i][j] != i) break; } grayRamp = (i == cMapSize); // didn't break out too soon } bool isGray = h.imageType == TargaRawBW || h.imageType == TargaRunBW || grayRamp && (h.imageType == TargaRawColormap || h.imageType == TargaRunColormap); bool isRaw = h.imageType == TargaRawBW || h.imageType == TargaRawRGB || h.imageType == TargaRawRGB && isGray; // Determine the image shape CShape sh(h.width, h.height, (isGray) ? 1 : 4); // Allocate the image if necessary img.ReAllocate(sh, false); // Construct a run-length code reader CTargaRLC rlc(! isRaw); // Read in the rows for (int y = 0; y < sh.height; y++) { int yr = reverseRows ? sh.height-1-y : y; uchar* ptr = (uchar *) img.PixelAddress(0, yr, 0); if (fileBytes == sh.nBands && isRaw) { // Special case for raw image, same as destination int n = sh.width*sh.nBands; if (fread(ptr, sizeof(uchar), n, stream) != n) throw CError("ReadFileTGA(%s): file is too short", filename); } else { // Read one pixel at a time for (int x = 0; x < sh.width; x++, ptr += sh.nBands) { uchar* buf = rlc.getBytes(fileBytes, stream); if (fileBytes == 1 && sh.nBands == 1) { ptr[0] = buf[0]; } else if (fileBytes == 1 && sh.nBands == 4) { for (int i = 0; i < 3; i++) ptr[i] = (isGray) ? buf[0] : colormap[buf[0]][i]; ptr[3] = 255; // full alpha; } else if ((fileBytes == 3 || fileBytes == 4) && sh.nBands == 4) { int i; for (i = 0; i < fileBytes; i++) ptr[i] = buf[i]; if (i == 3) // missing alpha channel ptr[3] = 255; // full alpha; } else throw CError("ReadFileTGA(%s): unhandled pixel depth or # of bands", filename); } } } if (fclose(stream)) throw CError("ReadFileTGA(%s): error closing file", filename); }
void ReadFilePNG(CByteImage& img, const char* filename) { // open the PNG input file FILE *stream = fopen(filename, "rb"); if (stream == 0) throw CError("ReadFilePNG: could not open %s", filename); // first check the eight byte PNG signature png_byte pbSig[8]; fread(pbSig, 1, 8, stream); if (!png_check_sig(pbSig, 8)) { fclose(stream); throw CError("ReadFilePNG: invalid PNG signature"); } // create the two png(-info) structures png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)pngfile_error, (png_error_ptr)NULL); if (!png_ptr) { fclose(stream); throw CError("ReadFilePNG: error creating png structure"); } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(stream); throw CError("ReadFilePNG: error creating png structure"); } png_init_io(png_ptr, stream); png_set_sig_bytes(png_ptr, 8); // read all PNG info up to image data png_read_info(png_ptr, info_ptr); // get width, height, bit-depth and color-type int width, height, bits, colorType, nBands; png_uint_32 pwidth, pheight; png_get_IHDR(png_ptr, info_ptr, &pwidth, &pheight, //(png_uint_32 *)&width, (png_uint_32 *)&height, &bits, &colorType, NULL, NULL, NULL); width = pwidth; height = pheight; nBands = (int)png_get_channels(png_ptr, info_ptr); if (DEBUG_ImageIOpng) fprintf(stderr, " w=%d, h=%d, %2d bits, %s, nB=%d", width, height, bits, colorType == PNG_COLOR_TYPE_GRAY ? "gray" : colorType == PNG_COLOR_TYPE_PALETTE ? "plt " : colorType == PNG_COLOR_TYPE_RGB ? "rgb " : colorType == PNG_COLOR_TYPE_RGB_ALPHA ? "rgba" : colorType == PNG_COLOR_TYPE_GRAY_ALPHA ? "gr-a" : "??? ", nBands); // get rid of lower-order byte in 16-bit images // TODO: could allow this and read in IntImage in this case... if (bits == 16) png_set_strip_16(png_ptr); // change palette color into RGB if (colorType == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); // want at least 8 bits if (bits < 8) png_set_expand(png_ptr); // if there is a transparent palette entry, create alpha channel if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr); // make gray images with alpha channel into RGBA -- TODO: or just ignore alpha? if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA) // colorType == PNG_COLOR_TYPE_GRAY // but leave gray images alone png_set_gray_to_rgb(png_ptr); // set the background color to draw transparent and alpha images over. // only needed for gray images with alpha if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA || colorType == PNG_COLOR_TYPE_GRAY) { png_color_16 *pBackground; if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); } // if required set gamma conversion // this seems to cause problems, so let's just leave gamma alone. //double gamma; //if (png_get_gAMA(png_ptr, info_ptr, &gamma)) { // //fprintf(stderr, "\n reading gamma %lf\n", gamma); //png_set_gamma(png_ptr, 1.0, gamma); //} // we need colors in BGR order, not RGB png_set_bgr(png_ptr); // always convert 3-band to 4-band images (add alpha): if (colorType == PNG_COLOR_TYPE_RGB) png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER); // after the transformations have been registered update info_ptr data png_read_update_info(png_ptr, info_ptr); // get again width, height and the new bit-depth and color-type png_get_IHDR(png_ptr, info_ptr, &pwidth, &pheight, //(png_uint_32 *)&width, (png_uint_32 *)&height, &bits, &colorType, NULL, NULL, NULL); width = pwidth; height = pheight; nBands = (int)png_get_channels(png_ptr, info_ptr); if (DEBUG_ImageIOpng) fprintf(stderr, " -> w=%d, h=%d, %2d bits, %s, nB=%d\n", width, height, bits, colorType == PNG_COLOR_TYPE_GRAY ? "gray" : colorType == PNG_COLOR_TYPE_PALETTE ? "plt " : colorType == PNG_COLOR_TYPE_RGB ? "rgb " : colorType == PNG_COLOR_TYPE_RGB_ALPHA ? "rgba" : colorType == PNG_COLOR_TYPE_GRAY_ALPHA ? "gr-a" : "??? ", nBands); if (! (nBands==1 || nBands==3 || nBands==4)) { fclose(stream); throw CError("ReadFilePNG: Can't handle nBands=%d", nBands); } // Set the image shape CShape sh(width, height, nBands); // Allocate the image if necessary img.ReAllocate(sh); // allocate a vector of row pointers std::vector<uchar *> rowPtrs; rowPtrs.resize(height); for (int y = 0; y<height; y++) rowPtrs[y] = &img.Pixel(0, y, 0); // read the whole image png_read_image(png_ptr, &rowPtrs[0]); // read the additional chunks in the PNG file (not really needed) png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(stream); }