예제 #1
0
Feature 
TinyImageFeatureExtractor::operator()(const CByteImage& img_) const
{
	CFloatImage tinyImg(_targetW, _targetH, 1);

	/******** BEGIN TODO ********/
	// Compute tiny image feature, output should be _targetW by _targetH a grayscale image
	// Steps are:
	// 1) Convert image to grayscale (see convertRGB2GrayImage in Utils.h)
	// 2) Resize image to be _targetW by _targetH
	// 
	// Useful functions:
	// convertRGB2GrayImage, TypeConvert, WarpGlobal

	
	CByteImage gray;
	CFloatImage grayF;
	convertRGB2GrayImage(img_, gray);
	TypeConvert(gray, grayF);
	CTransform3x3 scale = CTransform3x3::Scale(1.* img_.Shape().width / _targetW,
											   1.* img_.Shape().height/ _targetH);
	
	WarpGlobal(grayF, tinyImg, scale, eWarpInterpLinear);

	 

	/******** END TODO ********/

	return tinyImg;
}
예제 #2
0
cv::Mat flowToColor(const cv::Mat & flow, float max) {
    assert(flow.channels() == 2);
    
    int rows = flow.rows;
    int cols = flow.cols;
    
    CFloatImage cFlow(cols, rows, 2);
    
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cFlow.Pixel(j, i, 0) = flow.at<cv::Vec2f>(i, j)[0];
            cFlow.Pixel(j, i, 1) = flow.at<cv::Vec2f>(i, j)[1];
        }
    }
    
    CByteImage cImage;
    MotionToColor(cFlow, cImage, max);
    
    assert(cImage.Shape().height == rows);
    assert(cImage.Shape().width == cols);
    assert(cImage.Shape().nBands == 3);
    
    cv::Mat image(rows, cols, CV_8UC3, cv::Scalar(0, 0, 0));
    
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            image.at<cv::Vec3b>(i, j)[0] = cImage.Pixel(j, i, 0);
            image.at<cv::Vec3b>(i, j)[1] = cImage.Pixel(j, i, 1);
            image.at<cv::Vec3b>(i, j)[2] = cImage.Pixel(j, i, 2);
        }
    }    
    return image;
}
예제 #3
0
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;
			}
		}
	}
}
예제 #4
0
// Flip the y-axis of an image
void FlipImage(CByteImage &imageIn, CByteImage &imageOut) {
    CShape sh = imageIn.Shape();

    assert(imageIn.Shape().nBands == imageIn.Shape().nBands);
    for (int y=0; y<sh.height; y++) {
        for (int x=0; x<sh.width; x++) {
            for (int c=0; c<sh.nBands; c++) {
                imageOut.Pixel(x,sh.height-y-1,c) = imageIn.Pixel(x,y,c);
            }
        }
    }
}
예제 #5
0
void setDisparities(CByteImage disp, MRF *mrf)
{
    CShape sh = disp.Shape();
    int width = sh.width, height = sh.height;

    int n = 0;
    for (int y = 0; y < height; y++) {
	uchar *row = &disp.Pixel(0, y, 0);
	for (int x = 0; x < width; x++) {
	    mrf->setLabel(n++, row[x]);
	}
    }
}
예제 #6
0
파일: mrfstereo.cpp 프로젝트: clusty/vision
void computeCues(CByteImage im1, MRF::CostVal *&hCue, MRF::CostVal *&vCue,
		 int gradThresh, int gradPenalty) {
    CShape sh = im1.Shape();
    int width = sh.width, height = sh.height, nB = sh.nBands;
    hCue = new MRF::CostVal[width * height];
    vCue = new MRF::CostVal[width * height];

    int nColors = __min(3, nB);

    // below we compute sum of squared colordiffs, so need to adjust threshold accordingly (results in RMS)
    gradThresh *= nColors * gradThresh;

    //sh.nBands=1;
    //CByteImage hc(sh), vc(sh);
    int n = 0;
    for (int y = 0; y < height; y++) {
	for (int x = 0; x < width; x++) {
	    uchar *pix   = &im1.Pixel(x, y, 0);
	    uchar *pix1x = &im1.Pixel(x + (x < width-1), y, 0);
	    uchar *pix1y = &im1.Pixel(x, y + (y < height-1), 0);
	    int sx = 0, sy = 0;
	    for (int b = 0; b < nColors; b++) {
		int dx = pix[b] - pix1x[b];
		int dy = pix[b] - pix1y[b];
		sx += dx * dx;
		sy += dy * dy;
	    }
	    hCue[n] = (sx < gradThresh ? gradPenalty : 1);
	    vCue[n] = (sy < gradThresh ? gradPenalty : 1);
	    //hc.Pixel(x, y, 0) = 100*hCue[n];
	    //vc.Pixel(x, y, 0) = 100*vCue[n];
	    n++;
	}
    }
    //WriteImageVerb(hc, "hcue.png", true);
    //WriteImageVerb(vc, "vcue.png", true);
    //exit(1);
}
// Convert CFloatImage to CByteImage.
void convertToByteImage(CFloatImage &floatImage, CByteImage &byteImage) {
    CShape sh = floatImage.Shape();

    assert(floatImage.Shape().nBands == byteImage.Shape().nBands);
    for (int y=0; y<sh.height; y++) {
        for (int x=0; x<sh.width; x++) {
            for (int c=0; c<sh.nBands; c++) {
		float value = floor(255*floatImage.Pixel(x,y,c) + 0.5f);

		if (value < byteImage.MinVal()) {
                    value = byteImage.MinVal();
		}
		else if (value > byteImage.MaxVal()) {
                    value = byteImage.MaxVal();
		}

		// We have to flip the image and reverse the color
		// channels to get it to come out right.  How silly!
		byteImage.Pixel(x,sh.height-y-1,sh.nBands-c-1) = (uchar) value;
            }
        }
    }
}
예제 #8
0
bool LoadImageFile(const char *filename, CByteImage &image)
{
	// Load the query image.
	printf("%s\n", filename);
	Fl_Shared_Image *fl_image = Fl_Shared_Image::get(filename);

	if (fl_image == NULL) {
		printf("TGA\n");
		ReadFile(image, filename);
		return true;
	} else {
		printf("Not TGA\n");
		CShape sh(fl_image->w(), fl_image->h(), 4);
		image = CByteImage(sh);

	    // Convert the image to the CImage format.
	    if (!convertImage(fl_image, image)) {
		    printf("couldn't convert image to RGB format\n");
		    return false;
	    }

		/* Set the alpha channel to 1 everywhere */
		int w = sh.width;
		int h = sh.height;

		sh = image.Shape();
		// printf("shape: %d, %d, %d\n", sh.width, sh.height, sh.nBands);
		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {
				image.Pixel(x, y, 3) = 255;
			}
		}

        return true;
    }
}
예제 #9
0
/******************* TO DO 4 *********************
 * AccumulateBlend:
 *	INPUT:
 *		img: a new image to be added to acc
 *		acc: portion of the accumulated image where img is to be added
 *		M: translation matrix for calculating a bounding box
 *		blendWidth: width of the blending function (horizontal hat function;
 *	    try other blending functions for extra credit)
 *	OUTPUT:
 *		add a weighted copy of img to the subimage specified in acc
 *		the first 3 band of acc records the weighted sum of pixel colors
 *		the fourth band of acc records the sum of weight
 */
static void AccumulateBlend(CByteImage& img, CFloatImage& acc, CTransform3x3 M, float blendWidth)
{
    /* Compute the bounding box of the image of the image */
    int bb_min_x, bb_min_y, bb_max_x, bb_max_y;
    ImageBoundingBox(img, M, bb_min_x, bb_min_y, bb_max_x, bb_max_y);

	int imgWidth = img.Shape().width;
	int imgHeight = img.Shape().height;

    CTransform3x3 Minv = M.Inverse();

    for (int y = bb_min_y; y <= bb_max_y; y++) {
        for (int x = bb_min_x; x < bb_max_x; x++) {
            /* Check bounds in destination */
            if (x < 0 || x >= acc.Shape().width || 
                y < 0 || y >= acc.Shape().height)
                continue;

            /* Compute source pixel and check bounds in source */
            CVector3 p_dest, p_src;
            p_dest[0] = x;
            p_dest[1] = y;
            p_dest[2] = 1.0;

            p_src = Minv * p_dest;

            float x_src = (float) (p_src[0] / p_src[2]);
            float y_src = (float) (p_src[1] / p_src[2]);

            if (x_src < 0.0 || x_src >= img.Shape().width - 1 ||
                y_src < 0.0 || y_src >= img.Shape().height - 1)
                continue;

            int xf = (int) floor(x_src);
            int yf = (int) floor(y_src);
            int xc = xf + 1;
            int yc = yf + 1;

            /* Skip black pixels */
            if (img.Pixel(xf, yf, 0) == 0x0 && 
                img.Pixel(xf, yf, 1) == 0x0 && 
                img.Pixel(xf, yf, 2) == 0x0)
                continue;

            if (img.Pixel(xc, yf, 0) == 0x0 && 
                img.Pixel(xc, yf, 1) == 0x0 && 
                img.Pixel(xc, yf, 2) == 0x0)
                continue;

            if (img.Pixel(xf, yc, 0) == 0x0 && 
                img.Pixel(xf, yc, 1) == 0x0 && 
                img.Pixel(xf, yc, 2) == 0x0)
                continue;

            if (img.Pixel(xc, yc, 0) == 0x0 && 
                img.Pixel(xc, yc, 1) == 0x0 && 
                img.Pixel(xc, yc, 2) == 0x0)
                continue;

            
            double weight = 1.0;

			// *** BEGIN TODO ***
			// set weight properly
			//(see mosaics lecture slide on "feathering") P455 on notebook
			//Q:How to find the invalid distance ? -> 
	
			double distance = ((imgWidth - x - 1)*(imgWidth - x - 1) + (imgHeight - y - 1)*(imgHeight - y - 1));
			if (distance < blendWidth)
			{
				weight = distance / blendWidth;
			}

            
			// *** END TODO ***	

			acc.Pixel(x, y, 0) += (float) (weight * img.PixelLerp(x_src, y_src, 0));
            acc.Pixel(x, y, 1) += (float) (weight * img.PixelLerp(x_src, y_src, 1));
            acc.Pixel(x, y, 2) += (float) (weight * img.PixelLerp(x_src, y_src, 2));
            acc.Pixel(x, y, 3) += (float) weight;
        }
    }
}
예제 #10
0
void evaldisp(CFloatImage disp, CFloatImage gtdisp, CByteImage mask, float badthresh, int maxdisp, int rounddisp)
{
    CShape sh = gtdisp.Shape();
    CShape sh2 = disp.Shape();
    CShape msh = mask.Shape();
    int width = sh.width, height = sh.height;
    int width2 = sh2.width, height2 = sh2.height;
    int scale = width / width2;

    if ((!(scale == 1 || scale == 2 || scale == 4))
	|| (scale * width2 != width)
	|| (scale * height2 != height)) {
	printf("   disp size = %4d x %4d\n", width2, height2);
	printf("GT disp size = %4d x %4d\n", width,  height);
	throw CError("GT disp size must be exactly 1, 2, or 4 * disp size");
    }

    int usemask = (msh.width > 0 && msh.height > 0);
    if (usemask && (msh != sh))
	throw CError("mask image must have same size as GT\n");

    int n = 0;
    int bad = 0;
    int invalid = 0;
    float serr = 0;
    for (int y = 0; y < height; y++) {
	for (int x = 0; x < width; x++) {
	    float gt = gtdisp.Pixel(x, y, 0);
	    if (gt == INFINITY) // unknown
		continue;
	    float d = scale * disp.Pixel(x / scale, y / scale, 0);
		float maxd = scale * maxdisp; // max disp range
	    int valid = (d != INFINITY && d <= maxd * 1000);
	    if (valid) {
		d = __max(0, __min(maxd, d)); // clip disps to max disp range
	    }
	    if (valid && rounddisp)
		d = round(d);
	    float err = fabs(d - gt);
	    if (usemask && mask.Pixel(x, y, 0) != 255) { // don't evaluate pixel
	    } else {
		n++;
		if (valid) {
		    serr += err;
		    if (err > badthresh) {
			bad++;
		    }
		} else {// invalid (i.e. hole in sparse disp map)
		    invalid++;
		}
	    }
	}
    }
    float badpercent =  100.0*bad/n;
    float invalidpercent =  100.0*invalid/n;
    float totalbadpercent =  100.0*(bad+invalid)/n;
    float avgErr = serr / (n - invalid); // CHANGED 10/14/2014 -- was: serr / n
    //printf("mask  bad%.1f  invalid  totbad   avgErr\n", badthresh);
    printf("%4.1f  %6.2f  %6.2f   %6.2f  %6.2f\n",   100.0*n/(width * height),
	   badpercent, invalidpercent, totalbadpercent, avgErr);
}
예제 #11
0
파일: mrfstereo.cpp 프로젝트: clusty/vision
void computeDSI(CByteImage im1,       // source (reference) image
		CByteImage im2,       // destination (match) image
		MRF::CostVal *&dsi,   // computed cost volume
		int nD,               // number of disparities
		int birchfield,       // use Birchfield/Tomasi costs
		int squaredDiffs,     // use squared differences
		int truncDiffs)       // truncated differences
{
    CShape sh = im1.Shape();
    int width = sh.width, height = sh.height, nB = sh.nBands;
    dsi = new MRF::CostVal[width * height * nD];

    int nColors = __min(3, nB);

    // worst value for sumdiff below 
    int worst_match = nColors * (squaredDiffs ? 255 * 255 : 255);
    // truncation threshold - NOTE: if squared, don't multiply by nColors (Eucl. dist.)
    int maxsumdiff = squaredDiffs ? truncDiffs * truncDiffs : nColors * abs(truncDiffs);
    // value for out-of-bounds matches
    int badcost = __min(worst_match, maxsumdiff);

    int dsiIndex = 0;
    for (int y = 0; y < height; y++) {
	for (int x = 0; x < width; x++) {
	    uchar *pix1 = &im1.Pixel(x, y, 0);
	    for (int d = 0; d < nD; d++) {
		int x2 = x-d;
		int dsiValue;
                if (x2 >= 0 && d < nD) { // in bounds
		    uchar *pix2 = &im2.Pixel(x2, y, 0);
                    int sumdiff = 0;
                    for (int b = 0; b < nColors; b++) {
			int diff = 0;
			if (birchfield) {
			    // Birchfield/Tomasi cost
			    int im1c = pix1[b];
			    int im1l = x == 0?   im1c : (im1c + pix1[b - nB]) / 2;
			    int im1r = x == width-1? im1c : (im1c + pix1[b + nB]) / 2;
			    int im2c = pix2[b];
			    int im2l = x2 == 0?   im2c : (im2c + pix2[b - nB]) / 2;
			    int im2r = x2 == width-1? im2c : (im2c + pix2[b + nB]) / 2;
			    int min1 = __min(im1c, __min(im1l, im1r));
			    int max1 = __max(im1c, __max(im1l, im1r));
			    int min2 = __min(im2c, __min(im2l, im2r));
			    int max2 = __max(im2c, __max(im2l, im2r));
			    int di1 = __max(0, __max(im1c - max2, min2 - im1c));
			    int di2 = __max(0, __max(im2c - max1, min1 - im2c));
			    diff = __min(di1, di2);
			} else {
			    // simple absolute difference
			    int di = pix1[b] - pix2[b];
			    diff = abs(di);
			}
			// square diffs if requested (Birchfield too...)
			sumdiff += (squaredDiffs ? diff * diff : diff);
                    }
		    // truncate diffs
		    dsiValue = __min(sumdiff, maxsumdiff);
                } else { // out of bounds: use maximum truncated cost
		    dsiValue = badcost;
		}
		//int x0=-140, y0=-150;
		//if (x==x0 && y==y0)
		//    printf("dsi(%d,%d,%2d)=%3d\n", x, y, d, dsiValue); 

		// The cost of pixel p and label l is stored at dsi[p*nLabels+l]
		dsi[dsiIndex++] = dsiValue;
	    }
	}
    }
    //exit(1);
}
예제 #12
0
/******************* TO DO *********************
* AccumulateBlend:
*	INPUT:
*		img: a new image to be added to acc
*		acc: portion of the accumulated image where img is to be added
*       M: the transformation mapping the input image 'img' into the output panorama 'acc'
*		blendWidth: width of the blending function (horizontal hat function;
*	    try other blending functions for extra credit)
*	OUTPUT:
*		add a weighted copy of img to the subimage specified in acc
*		the first 3 band of acc records the weighted sum of pixel colors
*		the fourth band of acc records the sum of weight
*/
static void AccumulateBlend(CByteImage& img, CFloatImage& acc, CTransform3x3 M, float blendWidth)
{
    // BEGIN TODO
    // Fill in this routine
	// get shape of acc and img
	CShape sh = img.Shape();
    int width = sh.width;
    int height = sh.height;
	CShape shacc = acc.Shape();
    int widthacc = shacc.width;
    int heightacc = shacc.height;
	
	// get the bounding box of img in acc
	int min_x, min_y, max_x, max_y;
	ImageBoundingBox(img, M, min_x, min_y, max_x, max_y);

	CVector3 p;
	double newx, newy;

	// Exposure Compensation
	double lumaScale = 1.0;
	double lumaAcc = 0.0;
	double lumaImg = 0.0;
	int cnt = 0;

	for (int ii = min_x; ii < max_x; ii++)
		for (int jj = min_y; jj < max_y; jj++)
		{
			// flag: current pixel black or not
			bool flag = false;
			p[0] = ii; p[1] = jj; p[2] = 1;
			p = M.Inverse() * p;
			newx = p[0] / p[2];
			newy = p[1] / p[2];
			// If in the overlapping region
			if (newx >=0 && newx < width && newy >=0 && newy < height)
			{
				if (acc.Pixel(ii,jj,0) == 0 &&
					acc.Pixel(ii,jj,1) == 0 &&
					acc.Pixel(ii,jj,2) == 0)
					flag = true;
				if (img.PixelLerp(newx,newy,0) == 0 &&
					img.PixelLerp(newx,newy,1) == 0 &&
					img.PixelLerp(newx,newy,2) == 0)
					flag = true;
				if (!flag)
				{
					// Compute Y using RGB (RGB -> YUV)
					lumaAcc = 0.299 * acc.Pixel(ii,jj,0) +
							   0.587 * acc.Pixel(ii,jj,1) +
							   0.114 * acc.Pixel(ii,jj,2);
					lumaImg = 0.299 * img.PixelLerp(newx,newy,0) +
							   0.587 * img.PixelLerp(newx,newy,1) +
							   0.114 * img.PixelLerp(newx,newy,2);
					
					if (lumaImg != 0)
					{
						double scale = lumaAcc / lumaImg;
						if (scale > 0.5 && scale < 2)
						{
							lumaScale += lumaAcc / lumaImg;
							cnt++;
						}
					}
				}
			}
		}

	if (cnt != 0)
		lumaScale = lumaScale / (double)cnt;
	else lumaScale = 1.0;

	// add every pixel in img to acc, feather the region withing blendwidth to the bounding box,
	// pure black pixels (caused by warping) are not added
	double weight;
	
	for (int ii = min_x; ii < max_x; ii++)
		for (int jj = min_y; jj < max_y; jj++)
		{
			p[0] = ii; p[1] = jj; p[2] = 1;
			p = M.Inverse() * p;
			newx = p[0] / p[2];
			newy = p[1] / p[2];
			if ((newx >= 0) && (newx < width-1) && (newy >= 0) && (newy < height-1))
			{
				weight = 1.0;
				if ( (ii >= min_x) && (ii < (min_x+blendWidth)) )
					weight = (ii-min_x) / blendWidth;
				if ( (ii <= max_x) && (ii > (max_x-blendWidth)) )
					weight = (max_x-ii) / blendWidth;
				if (img.Pixel(iround(newx),iround(newy),0) == 0 &&
					img.Pixel(iround(newx),iround(newy),1) == 0 &&
					img.Pixel(iround(newx),iround(newy),2) == 0)
					weight = 0.0;

				double LerpR = img.PixelLerp(newx, newy, 0);
				double LerpG = img.PixelLerp(newx, newy, 1);
				double LerpB = img.PixelLerp(newx, newy, 2);
				
				double r = LerpR*lumaScale > 255.0 ? 255.0 : LerpR*lumaScale;
				double g = LerpG*lumaScale > 255.0 ? 255.0 : LerpG*lumaScale;
				double b = LerpB*lumaScale > 255.0 ? 255.0 : LerpB*lumaScale;
				acc.Pixel(ii,jj,0) += r * weight;
				acc.Pixel(ii,jj,1) += g * weight;
				acc.Pixel(ii,jj,2) += b * weight;
				acc.Pixel(ii,jj,3) += weight;
			}
		}
	
	printf("AccumulateBlend\n"); 

    // END TODO
}
예제 #13
0
Feature 
HOGFeatureExtractor::operator()(const CByteImage& img_) const
{
	/******** BEGIN TODO ********/
	// Compute the Histogram of Oriented Gradients feature
	// Steps are:
	// 1) Compute gradients in x and y directions. We provide the 
	//    derivative kernel proposed in the paper in _kernelDx and
	//    _kernelDy.
	// 2) Compute gradient magnitude and orientation
	// 3) Add contribution each pixel to HOG cells whose
	//    support overlaps with pixel. Each cell has a support of size
	//    _cellSize and each histogram has _nAngularBins.
	// 4) Normalize HOG for each cell. One simple strategy that is
	//    is also used in the SIFT descriptor is to first threshold
	//    the bin values so that no bin value is larger than some
	//    threshold (we leave it up to you do find this value) and
	//    then re-normalize the histogram so that it has norm 1. A more 
	//    elaborate normalization scheme is proposed in Dalal & Triggs
	//    paper but we leave that as extra credit.
	// 
	// Useful functions:
	// convertRGB2GrayImage, TypeConvert, WarpGlobal, Convolve

	
	int xCells = ceil(1.*img_.Shape().width  / _cellSize);
	int yCells = ceil(1.*img_.Shape().height / _cellSize);

	CFloatImage HOGHist(xCells, yCells, _nAngularBins);
	HOGHist.ClearPixels();

	CByteImage gray(img_.Shape());
	CFloatImage grayF(img_.Shape().width, img_.Shape().height, 1);

	convertRGB2GrayImage(img_, gray);
	TypeConvert(gray, grayF);

	CFloatImage diffX( img_.Shape()), diffY( img_.Shape());

	Convolve(grayF, diffX, _kernelDx);
	Convolve(grayF, diffY, _kernelDy);
	
	CFloatImage grad(grayF.Shape()), grad2(grayF.Shape());
	CFloatImage angl(grayF.Shape()), angl2(grayF.Shape());
	
	for (int y = 0; y <grayF.Shape().height; y++){
		for (int x = 0; x<grayF.Shape().width; x++) {
			grad2.Pixel(x,y,0) = (diffX.Pixel(x,y,0) * diffX.Pixel(x,y,0) +
							     diffY.Pixel(x,y,0) * diffY.Pixel(x,y,0));
			angl2.Pixel(x,y,0) = atan(diffY.Pixel(x,y,0) / abs(diffY.Pixel(x,y,0)));
		}
	}

	// Bilinear Filter
	ConvolveSeparable(grad2, grad, ConvolveKernel_121,ConvolveKernel_121,1);
	ConvolveSeparable(angl2, angl, ConvolveKernel_121,ConvolveKernel_121,1);
	//WriteFile(diffX, "angle.tga");
	//WriteFile(diffY, "angleG.tga");

	for (int y = 0; y <grayF.Shape().height; y++){
		for (int x = 0; x<grayF.Shape().width; x++) {
			// Fit in the bins
			int a = angl.Pixel(x,y,0) / 3.14 * (_nAngularBins) + _nAngularBins/2;		
			// Histogram
			HOGHist.Pixel(floor(1.*x / _cellSize),
						  floor(1.*y / _cellSize),
						  a) += grad.Pixel(x,y,0);
		}
	}
	
	// Normalization 
	float threshold = 0.7;
	for (int y = 0; y < yCells; y++){
		for (int x = 0; x < xCells; x++){
			float total = 0;
			for (int a = 0; a < _nAngularBins; a++) {
				if (HOGHist.Pixel(x,y,a) > threshold)
					HOGHist.Pixel(x,y,a) = threshold;
				// Sum for normalization
				total += HOGHist.Pixel(x,y,a);
			}
			for (int a = 0;a< _nAngularBins; a++) {
				HOGHist.Pixel(x,y,a) /= total;
				
			}
		}
	}
	
	return HOGHist;
	/******** END TODO ********/

}
예제 #14
0
// TODO: the following function should go somewhere else, perhaps in ImageIO.cpp
// Make sure the image has the smallest number of bands before writing.
// That is, if it's 4 bands with full alpha, reduce to 3 bands.  
// If it's 3 bands with constant colors, make it 1-band.
CByteImage removeRedundantBands(CByteImage img)
{
    CShape sh = img.Shape();
	int w = sh.width, h = sh.height, nB = sh.nBands;
	int x, y;
	if (nB < 3)
		return img;

	// check if full alpha if alpha channel present
	bool fullAlpha = true;
	if (nB == 4) {
		for (y = 0; y < h && fullAlpha; y++) {
			uchar *pix = &img.Pixel(0, y, 0);
			for (x = 0; x < w; x++) {
				if (pix[3] != 255) {
					fullAlpha = false;
					break;
				}
				pix += nB;
			}
		}
	}
	if (!fullAlpha)
		return img;

	// check for equal colors
	bool equalColors = true;
	for (y = 0; y < h && equalColors; y++) {
		uchar *pix = &img.Pixel(0, y, 0);
		for (x = 0; x < w; x++) {
			if (pix[0] != pix[1] ||
				pix[0] != pix[2] ||
				pix[1] != pix[2]) {
					equalColors = false;
					break;
				}
				pix += nB;
		}
	}
	// at this point, if nB == 4 we can reduce to at least 3 bands,
	// and if equalColors we can reduce to 1 band.
	if (! equalColors && nB < 4)
		return img;

	int newNB = equalColors ? 1 : 3;

	if (DEBUG_ImageIOpng)
		fprintf(stderr, "reducing from %d to %d bands\n", nB, newNB);

	CShape sh2(w, h, newNB);
	CByteImage img2(sh2);
	
	for (y = 0; y < h; y++) {
		uchar *pix = &img.Pixel(0, y, 0);
		uchar *pix2 = &img2.Pixel(0, y, 0);
		for (x = 0; x < w; x++) {
			for (int b = 0; b < newNB; b++) {
				pix2[b] = pix[b];
			}
			pix += nB;
			pix2 += newNB;
		}
	}

	return img2;
}
예제 #15
0
void WriteFilePNG(CByteImage img, const char* filename)
{
	img = removeRedundantBands(img);

    CShape sh = img.Shape();
    int width = sh.width, height = sh.height, nBands = sh.nBands;

	// Make sure the image has the smallest number of bands before writing.
	// That is, if it's 4 bands with full alpha, reduce to 3 bands.  
	// If it's 3 bands with constant colors, make it 1-band.

    FILE *stream = fopen(filename, "wb");
    if (stream == 0)
        throw CError("WriteFilePNG: could not open %s", filename);

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
      (png_error_ptr)pngfile_error, (png_error_ptr)NULL);

	if (!png_ptr) {
        fclose(stream);
		throw CError("WriteFilePNG: error creating png structure");
	}

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        fclose(stream);
		throw CError("WriteFilePNG: error creating png structure");
    }

	png_init_io(png_ptr, stream);

	int bits = 8;
	int colortype =
		nBands == 1 ? PNG_COLOR_TYPE_GRAY :
		nBands == 3 ? PNG_COLOR_TYPE_RGB :
	                  PNG_COLOR_TYPE_RGB_ALPHA;
	png_set_IHDR(png_ptr, info_ptr, width, height, 
		bits, colortype,
		PNG_INTERLACE_NONE, 
		PNG_COMPRESSION_TYPE_DEFAULT, 
		PNG_FILTER_TYPE_DEFAULT);

	// write the file header information
	png_write_info(png_ptr, info_ptr);

	// swap the BGR pixels in the DiData structure to RGB
	png_set_bgr(png_ptr);

	//  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);

	// write the whole image
	png_write_image(png_ptr, &rowPtrs[0]);

	// write the additional chunks to the PNG file (not really needed)
	png_write_end(png_ptr, info_ptr);

	png_destroy_write_struct(&png_ptr, (png_infopp) NULL);

    fclose (stream);
}
예제 #16
0
int BlendPairs(int argc, const char *argv[])
{
    // Blend a sequence of images given the pairwise transformations
    if (argc < 5)
    {
        printf("usage: %s pairlist.txt outimg.tga blendWidth\n", argv[1]);
        return -1;
    }
    const char *pairlist= argv[2];
    const char *outfile = argv[3];
    float blendWidth    = (float) atof(argv[4]);

    // Open the list of image pairs
    FILE *stream = fopen(pairlist, "r");
    if (stream == 0)
        throw CError("%s: could not open the file %s", argv[1], pairlist);

    // Construct the list of images and translations
    CImagePositionV ipList;
    char line[1024], infile1[1024], infile2[1024];
    // float rel_t[2];
    CTransform3x3 M;

    int n;
    for (n = 0; fgets(line, 1024, stream); n++)
    {
        // Compute the position from the PREVIOUS displacement
        CImagePosition ip;

		if (n == 0) {
			ip.position = CTransform3x3::Translation(0.0, 0.0); /* Ident matrix */
			// ip.position = CTransform3x3::Rotation(45.0); /* Ident matrix */
		} else {
			ip.position = M * ipList[n-1].position;
		}

        // for (int k = 0; k < 2; k++)
        //    ip.position[k] = (n > 0) ? ipList[n-1].position[k] - rel_t[k] : 0.0f;

        // Read the line and push the image onto the list
        // if (sscanf(line, "%s %s %f %f", infile1, infile2,
        //           &rel_t[0], &rel_t[1]) != 4)
        //    throw CError("%s: error reading %s", argv[1], pairlist);

#if 0
        if (sscanf(line, "%s %s %lf %lf", infile1, infile2,
			&(M[0][2]), &(M[1][2])) != 4)
			throw CError("%s: error reading %s\n", argv[1], pairlist);
#else
        if (sscanf(line, "%s %s %lf %lf %lf %lf %lf %lf %lf %lf %lf", infile1, infile2,
			&(M[0][0]), &(M[0][1]), &(M[0][2]), 
			&(M[1][0]), &(M[1][1]), &(M[1][2]), 
			&(M[2][0]), &(M[2][1]), &(M[2][2])) != 11)
			throw CError("%s: error reading %s\n", argv[1], pairlist);
#endif

		// The coordinate system of the ImageLib images has y reflected -- so let's fix that!

		// M[1][2] = -M[1][2];

		ip.imgName = std::string(infile1);
		CByteImage imgTmp;
		ReadFile(imgTmp, infile1);
		ip.img = CByteImage(imgTmp.Shape());
		FlipImage(imgTmp, ip.img);

		ipList.push_back(ip);
	}

	// Read in the last image
	CImagePosition ip;

	// for (int k = 0; k < 2; k++)
	//     ip.position[k] = ipList[n-1].position[k] - rel_t[k];
	ip.position = M * ipList[n-1].position;

	ip.imgName = std::string(infile2);
	CByteImage imgTmp;
	ReadFile(imgTmp, infile2);
	ip.img = CByteImage(imgTmp.Shape());
	FlipImage(imgTmp, ip.img);

	ipList.push_back(ip);
	fclose(stream);

	CByteImage resultTmp = BlendImages(ipList, blendWidth);

	// Flip again
	CByteImage result(resultTmp.Shape());
	FlipImage(resultTmp, result);

	WriteFile(result, outfile);
	return 0;
}