예제 #1
0
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);
}
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);
		}
	}
}
예제 #3
0
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 fillImageWithDecompostion(const std::vector<Curve> & contours,
                               png::image<png::rgb_pixel> & output)
{
  // Color map for the DLL
  const png::rgb_pixel pixelColors[4] = {
    // redPixel
    png::rgb_pixel(255,0,0),
    // greenPixel
    png::rgb_pixel(0,255,0),
    // bluePixel
    png::rgb_pixel(0,0,255),
    // yellowPixel
    png::rgb_pixel(255,255,0)
  };

  typedef typename DLL::Segment<DLL_Type>   DLLSegment;
  Utils::GreedyDecomposition<DLLSegment> decompositor;

  unsigned int nbDLL = 0;
  for (typename std::vector<Curve>::const_iterator contourItor = contours.begin();
       contourItor != contours.end(); ++contourItor) {
    // decompose the current contour
    typename std::vector<DLLSegment> dlls = decompositor.decomposeCurve(*contourItor);
    // color each DLL segment into the output image
    // and display the points coordinates of the DLL segment on the console
    unsigned int colorIndex = 3;
    for (typename std::vector<DLLSegment>::const_iterator dllItor = dlls.begin();
         dllItor != dlls.end(); ++dllItor) {
      const Curve & curve = dllItor->getCurve();
      if (verbose)
        std::cout << "DLL " << ++nbDLL << ":\t" << *dllItor
                  << "\n\tPoints: ";
      for(typename Curve::const_iterator coordItor = curve.begin();
          coordItor != curve.end();
          ++coordItor) {
        output.set_pixel(coordItor->first, coordItor->second,
                         pixelColors[colorIndex]);
        if (verbose)
          std::cout << "(" << coordItor->first << ","
                    << coordItor->second << ") ";
      }
      if (verbose)
        std::cout << std::endl;
      colorIndex = (colorIndex + 1) % 3;
    }
  }
}
예제 #5
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);
				}
			}
		}
	}
}