void SGMStereo::setImageSize(const png::image<png::rgb_pixel>& leftImage, const png::image<png::rgb_pixel>& rightImage) { width_ = static_cast<int>(leftImage.get_width()); height_ = static_cast<int>(leftImage.get_height()); if (rightImage.get_width() != width_ || rightImage.get_height() != height_) { throw std::invalid_argument("[SGMStereo::setImageSize] sizes of left and right images are different"); } widthStep_ = width_ + 15 - (width_ - 1)%16; }
void otsuThresholding(png::image<png::gray_pixel> & image) { const int numPixels = image.get_width() * image.get_height(); const size_t maxPixelValue = static_cast<size_t>( std::numeric_limits<png::gray_pixel>::max()); // histogram generation std::vector<unsigned int> histogram(maxPixelValue + 1, 0); for (size_t i = 0; i < image.get_width(); ++i) for (size_t j = 0; j < image.get_height(); ++j) ++histogram[image.get_pixel(i,j)]; // computation of the probabilities of each density level std::vector<double> prob(maxPixelValue + 1); for (size_t i = 0; i <= maxPixelValue; ++i) { prob[i] = static_cast<double>(histogram[i]) / numPixels; } // omega & mu computation std::vector<double> omega(maxPixelValue + 1); std::vector<double> mu(maxPixelValue + 1); omega[0] = prob[0]; mu[0] = 0.0; for (size_t i = 1; i <= maxPixelValue; ++i) { omega[i] = omega[i-1] + prob[i]; mu[i] = mu[i-1] + i * prob[i]; } // sigma maximization // sigma stands for inter-class variance // and determines optimal threshold value std::vector<double> sigma(maxPixelValue + 1); size_t threshold = 0; double max_sigma = 0.0; for (size_t i = 0; i <= maxPixelValue-1; ++i) { if (omega[i] != 0.0 && omega[i] != 1.0) sigma[i] = square(mu[maxPixelValue] * omega[i] - mu[i]) / (omega[i] * (1.0 - omega[i])); else sigma[i] = 0.0; if (sigma[i] > max_sigma) { max_sigma = sigma[i]; threshold = i; } } // binarization for (size_t i = 0; i < image.get_width(); ++i) for (size_t j = 0; j < image.get_height(); ++j) if (image.get_pixel(i,j) > threshold) image.set_pixel(i,j, std::numeric_limits<png::gray_pixel>::max()); else image.set_pixel(i,j, 0); }
png::image<png::rgb_pixel_16> bumpier::model::calculate_normals(const png::image<png::gray_pixel_16>& input, double phi, space_type space) const { int width = input.get_width(), height = input.get_height(); png::image<png::rgb_pixel_16> output(width, height); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { int xmin = (x + width - 1) % width, ymin = (y + height - 1) % height, xmax = (x + 1) % width, ymax = (y + 1) % height; Eigen::Vector3f normal = (position(input, x, ymax) - position(input, x, ymin)).cross( position(input, xmax, y) - position(input, xmin, y)); if(space == tangent_space) normal = tangentspace(Eigen::Vector2f((float)x / width, (float)y / height)) * normal; normal.normalize(); normal = (normal.array() * 0.5 + 0.5) * 0xFFFF; output.set_pixel(x, y, png::rgb_pixel_16(normal[0], normal[1], normal[2])); } return output; }
void dig_riverbed(int i, int j, png::gray_pixel_16 depth, png::image<png::gray_pixel_16>& topomap) { png::gray_pixel_16 cur_val,new_val,brush_depth; int brush_radius=2; int width = topomap.get_width(); int height = topomap.get_height(); for (int i_=i-brush_radius; i_<=i+brush_radius; i_++) { for(int j_=j-brush_radius; j_<=j+brush_radius; j_++) { if (i_<0||i_>width||j_<0||j_>=height) continue; double i_dist=i_-i; double j_dist=j_-j; double dist=sqrt(i_dist*i_dist+j_dist*j_dist); if(dist>brush_radius) continue; //double brush_depth_dbl = depth - depth*sin(dist/brush_radius*M_PI/2); double brush_depth_dbl = depth*cos(dist/brush_radius*M_PI/2); if(brush_depth_dbl < 0) brush_depth_dbl = 0; brush_depth = brush_depth_dbl; cur_val = topomap.get_pixel(i_,j_); if(brush_depth >= cur_val) new_val = 0; else new_val = cur_val - brush_depth; if (new_val < cur_val) topomap.set_pixel(i_,j_,new_val); } } }
void binaryImageToNegative(png::image<png::gray_pixel> & image) { for (size_t i = 0; i < image.get_width(); ++i) for (size_t j = 0; j < image.get_height(); ++j) { image.set_pixel(i,j, (image.get_pixel(i,j) == 0 ? std::numeric_limits<png::gray_pixel>::max() : 0)); } }
void generate_image(png::image< pixel >& image) { typedef png::pixel_traits< pixel > traits; size_t colors = 1 << traits::get_bit_depth(); size_t size = colors / 2; image.resize(size, size); png::palette palette(colors); for (size_t c = 0; c < colors; ++c) { palette[c] = png::color(c * 255 / colors, (colors - c - 1) * 255 / colors, c * 255 / colors); } image.set_palette(palette); for (size_t j = 0; j < image.get_height(); ++j) { for (size_t i = 0; i < image.get_width(); ++i) { image.set_pixel(i, j, i + j); } } }
void makeSegmentBoundaryImage(const png::image<png::rgb_pixel>& inputImage, const png::image<png::gray_pixel_16>& segmentImage, std::vector< std::vector<int> >& boundaryLabels, png::image<png::rgb_pixel>& segmentBoundaryImage) { int width = static_cast<int>(inputImage.get_width()); int height = static_cast<int>(inputImage.get_height()); int boundaryTotal = static_cast<int>(boundaryLabels.size()); segmentBoundaryImage.resize(width, height); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { segmentBoundaryImage.set_pixel(x, y, inputImage.get_pixel(x, y)); } } int boundaryWidth = 2; for (int y = 0; y < height - 1; ++y) { for (int x = 0; x < width - 1; ++x) { int pixelLabelIndex = segmentImage.get_pixel(x, y); if (segmentImage.get_pixel(x + 1, y) != pixelLabelIndex) { for (int w = 0; w < boundaryWidth - 1; ++w) { if (x - w >= 0) segmentBoundaryImage.set_pixel(x - w, y, png::rgb_pixel(128, 128, 128)); } for (int w = 1; w < boundaryWidth; ++w) { if (x + w < width) segmentBoundaryImage.set_pixel(x + w, y, png::rgb_pixel(128, 128, 128)); } } if (segmentImage.get_pixel(x, y + 1) != pixelLabelIndex) { for (int w = 0; w < boundaryWidth - 1; ++w) { if (y - w >= 0) segmentBoundaryImage.set_pixel(x, y - w, png::rgb_pixel(128, 128, 128)); } for (int w = 1; w < boundaryWidth; ++w) { if (y + w < height) segmentBoundaryImage.set_pixel(x, y + w, png::rgb_pixel(128, 128, 128)); } } } } boundaryWidth = 7; for (int y = 0; y < height - 1; ++y) { for (int x = 0; x < width - 1; ++x) { int pixelLabelIndex = segmentImage.get_pixel(x, y); if (segmentImage.get_pixel(x + 1, y) != pixelLabelIndex) { png::rgb_pixel negativeSideColor, positiveSideColor; int pixelBoundaryIndex = -1; for (int boundaryIndex = 0; boundaryIndex < boundaryTotal; ++boundaryIndex) { if ((boundaryLabels[boundaryIndex][0] == pixelLabelIndex && boundaryLabels[boundaryIndex][1] == segmentImage.get_pixel(x + 1, y)) || (boundaryLabels[boundaryIndex][0] == segmentImage.get_pixel(x + 1, y) && boundaryLabels[boundaryIndex][1] == pixelLabelIndex)) { pixelBoundaryIndex = boundaryIndex; break; } } if (boundaryLabels[pixelBoundaryIndex][2] == 3) continue; else if (boundaryLabels[pixelBoundaryIndex][2] == 2) { negativeSideColor.red = 0; negativeSideColor.green = 225; negativeSideColor.blue = 0; positiveSideColor.red = 0; positiveSideColor.green = 225; positiveSideColor.blue = 0; } else if (pixelLabelIndex == boundaryLabels[pixelBoundaryIndex][boundaryLabels[pixelBoundaryIndex][2]]) { negativeSideColor.red = 225; negativeSideColor.green = 0; negativeSideColor.blue = 0; positiveSideColor.red = 0; positiveSideColor.green = 0; positiveSideColor.blue = 225; } else { negativeSideColor.red = 0; negativeSideColor.green = 0; negativeSideColor.blue = 225; positiveSideColor.red = 225; positiveSideColor.green = 0; positiveSideColor.blue = 0; } for (int w = 0; w < boundaryWidth - 1; ++w) { if (x - w >= 0) segmentBoundaryImage.set_pixel(x - w, y, negativeSideColor); } for (int w = 1; w < boundaryWidth; ++w) { if (x + w < width) segmentBoundaryImage.set_pixel(x + w, y, positiveSideColor); } } if (segmentImage.get_pixel(x, y + 1) != pixelLabelIndex) { png::rgb_pixel negativeSideColor, positiveSideColor; int pixelBoundaryIndex = -1; for (int boundaryIndex = 0; boundaryIndex < boundaryTotal; ++boundaryIndex) { if ((boundaryLabels[boundaryIndex][0] == pixelLabelIndex && boundaryLabels[boundaryIndex][1] == segmentImage.get_pixel(x, y + 1)) || (boundaryLabels[boundaryIndex][0] == segmentImage.get_pixel(x, y + 1) && boundaryLabels[boundaryIndex][1] == pixelLabelIndex)) { pixelBoundaryIndex = boundaryIndex; break; } } if (boundaryLabels[pixelBoundaryIndex][2] == 3) continue; else if (boundaryLabels[pixelBoundaryIndex][2] == 2) { negativeSideColor.red = 0; negativeSideColor.green = 225; negativeSideColor.blue = 0; positiveSideColor.red = 0; positiveSideColor.green = 225; positiveSideColor.blue = 0; } else if (pixelLabelIndex == boundaryLabels[pixelBoundaryIndex][boundaryLabels[pixelBoundaryIndex][2]]) { negativeSideColor.red = 225; negativeSideColor.green = 0; negativeSideColor.blue = 0; positiveSideColor.red = 0; positiveSideColor.green = 0; positiveSideColor.blue = 225; } else { negativeSideColor.red = 0; negativeSideColor.green = 0; negativeSideColor.blue = 225; positiveSideColor.red = 225; positiveSideColor.green = 0; positiveSideColor.blue = 0; } for (int w = 0; w < boundaryWidth - 1; ++w) { if (y - w >= 0) segmentBoundaryImage.set_pixel(x, y - w, negativeSideColor); } for (int w = 1; w < boundaryWidth; ++w) { if (y+ w < height) segmentBoundaryImage.set_pixel(x, y + w, positiveSideColor); } } } } }
Eigen::Vector3f bumpier::model::position(const png::image<png::gray_pixel_16>& image, int x, int y) const { return position(Eigen::Vector2f((float)x / image.get_width(), (float)y / image.get_height()), (float)image.get_pixel(x, y) / 0xFFFF); }