int StudentLocalization::getTopOfHead(const IntensityImage &image){
	for (int y = 0; y < image.getHeight(); y++){
		for (int x = 0; x < image.getWidth(); x++) {
			if (image.getPixel(x, y) == 0){
				return y;
			}
		}
	}
	return -1;
}
void HereBeDragons::HerLoveForWhoseDearLoveIRiseAndFall(const IntensityImage &src, cv::Mat &dst) {
	int w = src.getWidth();
	int h = src.getHeight();

	dst.create(h, w, CV_8UC1);

	for (int x = 0; x < dst.cols; x++) {
		for (int y = 0; y < dst.rows; y++) {
			dst.at<uchar>(y, x) = src.getPixel(x, y);
		}
	}
}
void IntensityImageStudent::set(const IntensityImage &other) {
	const int	SIZE = other.getSize();
	IntensityImage::set(other.getWidth(), other.getHeight());

	if (SIZE > 0) {
		delete[] pixelMap;
		pixelMap = new Intensity[SIZE];
		for (int i = 0; i < SIZE; i++) {
			pixelMap[i] = other.getPixel(i);
		}
	}
}
bool StudentLocalization::stepFindHead(const IntensityImage &image, FeatureMap &features) const {
	int yTop = getTopOfHead(image);
	int alpha = 13;
	int* histogram;
	int left, right;
	int diffFirstLast = -1, maxDiffFirstLast = -1;
	int ySides = -1;
	//number of slices the image will be 'cut' into for the histograms
	int count = ((image.getHeight() - yTop - 1) / alpha) + 1;

	for (int i = 0; i < count; i++) {
		//get histogram of current slice
		histogram = getHistogramX(image, alpha, yTop + i * alpha);
		findSidesInHistogram(histogram, image.getWidth(), &left, &right);
		//if no two sides have been found continue to the next slice
		if (left == -1 || right == -1) {
			continue;
		}

		//find the first peak gap between the left and right side to detect the position of the ears
		diffFirstLast = right - left;
		if (diffFirstLast > maxDiffFirstLast) {
			maxDiffFirstLast = diffFirstLast;
		}
		else {
			//if the gap is lower than the max, a peak has been found
			//and the y position of the ears will be set to the middle of the slice 
			//where the peak is detected
			ySides = yTop + (i + 1)  * alpha;
			break;
		}
	}
	//if no peak is detected return false
	if (ySides == -1) {
		return false;
	}

	//set the results in the feature map
	Point2D<double> * pointLeftSideHead = new Point2D<double>(left, ySides);
	Feature * leftSideHead = new Feature(Feature::FEATURE_HEAD_LEFT_SIDE, *pointLeftSideHead);
	features.putFeature(*leftSideHead);

	Point2D<double> * pointRightSideHead = new Point2D<double>(right, ySides);
	Feature * rightSideHead = new Feature(Feature::FEATURE_HEAD_RIGHT_SIDE, *pointRightSideHead);
	features.putFeature(*rightSideHead);

	Point2D<double> * pointTopOfHead = new Point2D<double>((left + right) / 2, yTop);
	Feature * topOfHead = new Feature(Feature::FEATURE_HEAD_TOP, *pointTopOfHead);
	features.putFeature(*topOfHead);
	
	return true;
}
void LuminosityAlgorithm::doAlgorithm(const RGBImage& input, IntensityImage& output)
{
	// Check image size
	if (input.getWidth() != output.getWidth() || input.getHeight() != output.getHeight()) {
		output.set(input.getWidth(), input.getHeight());
	}

	// Lunimosity Algorithm defined as
	// Gray = (Red * 0.2126 + Green * 0.7152 + Blue * 0.0722)
	for (int i = 0; i < input.getWidth()*input.getHeight(); i++) {
		RGB pixel = input.getPixel(i);
		output.setPixel(i, pixel.r * 0.2126 + pixel.g * 0.7152 + pixel.b * 0.0722);
	}
}
예제 #6
0
void drawFeatureDebugImage(IntensityImage &image, FeatureMap &features) {
	RGB colorRed(244, 67, 54);
	RGBImage * debug = ImageFactory::newRGBImage(image.getWidth(), image.getHeight());
	ImageIO::intensityToRGB(image, *debug);

	//Nose
	Point2D<double> noseLeft = features.getFeature(Feature::FEATURE_NOSE_END_LEFT)[0];
	Point2D<double> noseRight = features.getFeature(Feature::FEATURE_NOSE_END_RIGHT)[0];
	Point2D<double> nostrilLeft = features.getFeature(Feature::FEATURE_NOSTRIL_LEFT)[0];
	Point2D<double> nostrilRight = features.getFeature(Feature::FEATURE_NOSTRIL_RIGHT)[0];
	Point2D<double> noseBottom = features.getFeature(Feature::FEATURE_NOSE_BOTTOM)[0];


	//These (weird) methods can be used to draw debug points
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, noseLeft, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, noseRight, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, nostrilLeft, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, nostrilRight, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, noseBottom, colorRed);

	//Chin
	std::vector<Point2D<double>> points = features.getFeature(Feature::FEATURE_CHIN_CONTOUR).getPoints();
	for (size_t i = 0; i < points.size(); i++) {
		HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, points[i], colorRed);
	}

	//Eye
	Feature leftEye = features.getFeature(Feature::FEATURE_EYE_LEFT_RECT);
	Feature rightEye = features.getFeature(Feature::FEATURE_EYE_RIGHT_RECT);


	//These (weird) methods can be used to draw debug rects
	HereBeDragons::AsHisTriumphantPrizeProudOfThisPride(*debug, leftEye[0], leftEye[1], colorRed);
	HereBeDragons::AsHisTriumphantPrizeProudOfThisPride(*debug, rightEye[0], rightEye[1], colorRed);


	//Head
	Feature headTop = features.getFeature(Feature::FEATURE_HEAD_TOP);
	Feature headLeftNoseMiddle = features.getFeature(Feature::FEATURE_HEAD_LEFT_NOSE_MIDDLE);
	Feature headLeftNoseBottom = features.getFeature(Feature::FEATURE_HEAD_LEFT_NOSE_BOTTOM);
	Feature headRightNoseMiddle = features.getFeature(Feature::FEATURE_HEAD_RIGHT_NOSE_MIDDLE);
	Feature headRightNoseBottom = features.getFeature(Feature::FEATURE_HEAD_RIGHT_NOSE_BOTTOM);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, headTop[0], colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, headLeftNoseMiddle[0], colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, headLeftNoseBottom[0], colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, headRightNoseMiddle[0], colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, headRightNoseBottom[0], colorRed);

	//Mouth
	Point2D<double> mouthTop = features.getFeature(Feature::FEATURE_MOUTH_TOP)[0];
	Point2D<double> mouthBottom = features.getFeature(Feature::FEATURE_MOUTH_BOTTOM)[0];
	Point2D<double> mouthLeft = features.getFeature(Feature::FEATURE_MOUTH_CORNER_LEFT)[0];
	Point2D<double> mouthRight = features.getFeature(Feature::FEATURE_MOUTH_CORNER_RIGHT)[0];

	//This (weird) method can be used to draw a debug line
	HereBeDragons::ButRisingAtThyNameDothPointOutThee(*debug, mouthLeft, mouthRight, colorRed);

	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, mouthTop, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, mouthBottom, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, mouthLeft, colorRed);
	HereBeDragons::TriumphInLoveFleshStaysNoFatherReason(*debug, mouthRight, colorRed);

	ImageIO::saveRGBImage(*debug, ImageIO::getDebugFileName("feature-points-debug.png"));
	delete debug;
}
IntensityImageStudent::IntensityImageStudent(const IntensityImage &other) : IntensityImage(other.getWidth(), other.getHeight()), pixelMap(nullptr) {
	const int SIZE = other.getSize();
	if(SIZE > 0) {
		pixelMap = new Intensity[SIZE];
		for(int i = 0; i < SIZE; i++) {
			pixelMap[i] = other.getPixel(i);
		}
	}
}
IntensityImageStudent GaussianFilter::applyFilter(const IntensityImage &image)
{
	IntensityImageStudent filteredImage = IntensityImageStudent(image.getWidth() - 2 * radius, image.getHeight() - 2 * radius);
	
	for (int y = 0; y < filteredImage.getHeight(); y++){
		for (int x = 0; x < filteredImage.getWidth(); x++){
			double filteredIntensity = 0.0;
			for (unsigned int i = 0; i < gaussKernel.size(); i++){
				filteredIntensity += gaussKernel[i] * image.getPixel(x + (i % (2 * radius + 1)), y + i / (2 * radius + 1));
			}
			filteredImage.setPixel(x, y, static_cast<Intensity>(filteredIntensity));
		}
	}
	return filteredImage;
}
예제 #9
0
void Test::RunCannyTest(const RGBImage* in) {
	Gaussian smoother;
	Sobel sobel;
	Canny canny;
	StudentPreProcessing converter;

	double sigma = 1.6;
	int kernelSize = 5;

	// Convert RGB to Intensity
	IntensityImage* grey = ImageFactory::newIntensityImage(in->getWidth(), in->getHeight());
	grey = converter.stepToIntensityImage(*in);

	BaseTimer timer;
	int total = 0;
	for (int i = 0; i < 10; ++i) {
		timer.start();

		/* Start of Canny */

		// 1. Smooth Intensity with Gaussian
		IntensityImage* gaussian = ImageFactory::newIntensityImage(in->getWidth() - kernelSize, in->getHeight() - kernelSize);
		smoother.smoothImage(grey, gaussian, sigma, kernelSize);

		// 2. Find edges with Sobel (convolve X and Y separately for Canny)
		int sobelKernelSize = 3;
		IntensityImage* sobelX = ImageFactory::newIntensityImage(gaussian->getWidth() - sobelKernelSize, gaussian->getHeight() - sobelKernelSize);
		IntensityImage* sobelY = ImageFactory::newIntensityImage(gaussian->getWidth() - sobelKernelSize, gaussian->getHeight() - sobelKernelSize);
		sobel.filterXY(gaussian, sobelX, sobelY);

		// 3. Apply non-maximum suppresion
		IntensityImage* nonMaxSuppression = ImageFactory::newIntensityImage(sobelX->getWidth(), sobelX->getHeight());
		canny.nonMaximumSurpression(sobelX, sobelY, nonMaxSuppression);

		// 4. Apply hysteresis threshold
		IntensityImage* hysteresisThreshold = ImageFactory::newIntensityImage(sobelX->getWidth(), sobelX->getHeight());
		canny.threshold(nonMaxSuppression, hysteresisThreshold, 60, 70);

		timer.stop();
		std::cout << timer.elapsedMilliSeconds() << " ms" << std::endl;
		total += timer.elapsedMilliSeconds();
		timer.reset();

		if (i == 9)
			ImageIO::saveIntensityImage(*hysteresisThreshold, ImageIO::getDebugFileName("Canny.png"));
	}
	std::cout << "Average time per Canny edge detection: " << (total / 10) << " ms" << std::endl;
	std::cout << "Press the X in the console window to exit program" << std::endl;
}
bool StudentLocalization::stepFindHead(const IntensityImage &image, FeatureMap &features) const {
	Histogram AxisY(image, 50, 50, 0, 0, Axis::y);
	
	//determine top of the head

	int topHead = -1;

	for (int i = 0; i < AxisY.getSize(); ++i) {
		if (AxisY.getValue(i) > 2) {
			topHead = i;
			break;
		}
	}
	if (topHead == -1) {
		return false;
	}
	
	//determine sides

	int lastLeftX = -1;
	int lastRightX = -1;
	for (int y = topHead; y < image.getHeight(); y += 20) {
		Histogram layerX(image, 0, 0, y, (image.getHeight() - y - 20), Axis::x);
		
		//determine leftside of the head
		int leftX = -1;
		for (int i = 0; i < layerX.getSize(); ++i) {
			if (layerX.getValue(i) > 2) {
				leftX = i;
				break;
			}
		}

		//determine rightside of the head
		int rightX = -1;
		for (int i = layerX.getSize() - 1; i >= 0 ; --i) {
			if (layerX.getValue(i) > 2) {
				rightX = i;
				break;
			}
		}
		
		// if not both sides are found skip the rest of the loop
		if (leftX == -1 || rightX == -1) {
			continue;
		}

		int currentHeadWidth = rightX - leftX;
		int lastHeadWidth = lastRightX - lastLeftX;

		if (currentHeadWidth < lastHeadWidth) {
			Feature * headUpperBound = new Feature(Feature::FEATURE_HEAD_TOP, Point2D<double>(lastRightX - (currentHeadWidth / 2), topHead));
			Feature * headLeftBound = new Feature(Feature::FEATURE_HEAD_LEFT_SIDE, Point2D<double>(lastLeftX, y));
			Feature * headRightBound = new Feature(Feature::FEATURE_HEAD_RIGHT_SIDE, Point2D<double>(lastRightX, y));

			features.putFeature(*headUpperBound);
			features.putFeature(*headLeftBound);
			features.putFeature(*headRightBound);
					
			return true;
		}

		lastLeftX = leftX;
		lastRightX = rightX;
	}
	
	return false;
}