// Compute Simple descriptors. void ComputeSimpleDescriptors(CFloatImage &image, FeatureSet &features) { //Create grayscale image used for Harris detection CFloatImage grayImage=ConvertToGray(image); vector<Feature>::iterator i = features.begin(); while (i != features.end()) { Feature &f = *i; //these fields should already be set in the computeFeatures function int x = f.x; int y = f.y; // now get the 5x5 window surrounding the feature and store them in the features for(int row=(y-2); row<=(y+2); row++) { for(int col=(x-2); col<=(x+2); col++) { //if the pixel is out of bounds, assume it is black if(row<0 || row>=grayImage.Shape().height || col<0 || col>=grayImage.Shape().width) { f.data.push_back(0.0); } else { f.data.push_back(grayImage.Pixel(col,row,0)); } } } printf("feature num %d\n", i->id); i++; } }
void ComputeHarrisFeatures(CFloatImage &image, FeatureSet &features) { //Create grayscale image used for Harris detection CFloatImage grayImage=ConvertToGray(image); //Create image to store Harris values CFloatImage harrisImage(image.Shape().width,image.Shape().height,1); //Create image to store local maximum harris values as 1, other pixels 0 CByteImage harrisMaxImage(image.Shape().width,image.Shape().height,1); //compute Harris values puts harris values at each pixel position in harrisImage. //You'll need to implement this function. computeHarrisValues(grayImage, harrisImage); // Threshold the harris image and compute local maxima. You'll need to implement this function. computeLocalMaxima(harrisImage,harrisMaxImage); // Prints out the harris image for debugging purposes CByteImage tmp(harrisImage.Shape()); convertToByteImage(harrisImage, tmp); WriteFile(tmp, "harris.tga"); // TO DO-------------------------------------------------------------------- //Loop through feature points in harrisMaxImage and fill in information needed for //descriptor computation for each point above a threshold. We fill in id, type, //x, y, and angle. CFloatImage A(grayImage.Shape()); CFloatImage B(grayImage.Shape()); CFloatImage C(grayImage.Shape()); CFloatImage partialX(grayImage.Shape()); CFloatImage partialY(grayImage.Shape()); GetHarrisComponents(grayImage, A, B, C, &partialX, &partialY); int featureCount = 0; for (int y=0;y<harrisMaxImage.Shape().height;y++) { for (int x=0;x<harrisMaxImage.Shape().width;x++) { // Skip over non-maxima if (harrisMaxImage.Pixel(x, y, 0) == 0) continue; //TO DO--------------------------------------------------------------------- // Fill in feature with descriptor data here. Feature f; f.type = 2; f.id = featureCount++; f.x = x; f.y = y; f.angleRadians = GetCanonicalOrientation(x, y, A, B, C, partialX, partialY); //atan(partialY.Pixel(x, y, 0)/partialX.Pixel(x, y, 0)); // Add the feature to the list of features features.push_back(f); } } }
// Compute features using Harris corner detection method void ComputeHarrisFeatures(CFloatImage &image, FeatureSet &features) { // Create grayscale image used for Harris detection CFloatImage grayImage = ConvertToGray(image); // Create image to store Harris values CFloatImage harrisImage(image.Shape().width,image.Shape().height,1); // Create image to store local maximum harris values as 1, other pixels 0 CByteImage harrisMaxImage(image.Shape().width,image.Shape().height,1); // Create image to store orientation values CFloatImage orientationImage(image.Shape().width, image.Shape().height, 1); // Compute the harris score at each pixel position, storing the result in in harrisImage. computeHarrisValues(grayImage, harrisImage, orientationImage); // Threshold the harris image and compute local maxima. computeLocalMaxima(harrisImage,harrisMaxImage); // Save images CByteImage tmp(harrisImage.Shape()); CByteImage tmp2(harrisImage.Shape()); convertToByteImage(harrisImage, tmp); convertToByteImage(grayImage, tmp2); WriteFile(tmp2, "grayImg.tga"); WriteFile(tmp, "harris.tga"); WriteFile(harrisMaxImage, "harrisMax.tga"); // Loop through feature points in harrisMaxImage and fill in id, type, x, y, and angle // information needed for descriptor computation for each feature point, then add them // to feature set int id = 0; for (int y=0; y < harrisMaxImage.Shape().height; y++) { for (int x=0; x < harrisMaxImage.Shape().width; x++) { if (harrisMaxImage.Pixel(x, y, 0) == 1) { Feature f; f.id = id; f.type = 2; f.x = x; f.y = y; f.angleRadians = orientationImage.Pixel(x,y,0); features.push_back(f); id++; } } } }
int EPOSTPDriver::InnerRemixBmpInEPOS(byte* pBmpData, int bytePerLine, int bmpWidth, int bmpHeight, long lx, long ly, byte* pPrintData, int PrintDataLength) { mBmpWidth = bmpWidth; mBmpHeight = bmpHeight; if (!isGrayData(bmpWidth, bytePerLine)) { //灰度化 mpGrayData = ConvertToGray(pBmpData, bytePerLine, bmpWidth, bmpHeight); } else { mpGrayData = pBmpData; } //二值化 mpBlankInfo = ConvertToBW(mpGrayData, bmpWidth, bmpHeight); // releasePointers(&mpGrayData); delete[] mpGrayData; mpGrayData = nullptr; myxPos = 0; pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x40; myxPos += 2; int lYinPix = abs(ly) * 203.f / 254.f; int icounts = lYinPix / 255; if (ly > 0) { for (int i = 0; i < icounts; ++i) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x4a; pPrintData[myxPos + 2] = 0xff; myxPos += 3; } lYinPix &= 0xff; if (lYinPix > 0 || lYinPix < 0) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x4a; pPrintData[myxPos + 2] = (byte)lYinPix; myxPos += 3; } } long height = bmpHeight; int skipLines = 0; byte** DataBlock = 0; long ht = 0; long lXinPix = lx * 203 / 254; float skipBlankLineFactor = 1; float skipBlankColFactor = 1; while (ht < height) { skipLines = 0; byte tempByte = (byte)(0x80 >> (ht & 0x07)); while ((mpBlankInfo[ht >> 3] & tempByte) && (ht < height)) { ++ht; ++skipLines; } if (skipLines > 0) { int iSkipYpos = skipLines * skipBlankLineFactor; int iSkipCounts = iSkipYpos / 255; for (int i = 0; i < iSkipCounts; ++i) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x4a; pPrintData[myxPos + 2] = 0xff; myxPos += 3; } iSkipYpos &= 0xff; if (iSkipYpos != 0) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x4a; pPrintData[myxPos + 2] = (byte)iSkipYpos; myxPos += 3; } } if (ht >= height) { break; } if (lXinPix > 0) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x24; pPrintData[myxPos + 2] = lXinPix % 256; pPrintData[myxPos + 3] = lXinPix / 256; myxPos += 4; } DataBlock = get24Rows(ht); if (DataBlock == nullptr) { break; } ht += 24; twentyfourPointPerCol(DataBlock, pPrintData, 1); for (long i = 0; i < mBmpWidth; ++i) { delete[] DataBlock[i]; } delete[] DataBlock; } pPrintData[myxPos + 0] = 0x00; ++myxPos; return myxPos; }
// Compute MOPs descriptors. void ComputeMOPSDescriptors(CFloatImage &image, FeatureSet &features) { CFloatImage grayImage=ConvertToGray(image); CFloatImage blurredImage; Convolve(grayImage, blurredImage, ConvolveKernel_7x7); CFloatImage postHomography = CFloatImage(); CFloatImage gaussianImage = GetImageFromMatrix((float *)gaussian5x5Float, 5, 5); //first make the image invariant to changes in illumination by subtracting off the mean int grayHeight = grayImage.Shape().height; int grayWidth = grayImage.Shape().width; // now make this rotation invariant vector<Feature>::iterator featureIterator = features.begin(); while (featureIterator != features.end()) { Feature &f = *featureIterator; CTransform3x3 scaleTransform = CTransform3x3(); CTransform3x3 translationNegative; CTransform3x3 translationPositive; CTransform3x3 rotation; double scaleFactor = 41/8; scaleTransform[0][0] = scaleFactor; scaleTransform[1][1] = scaleFactor; translationNegative = translationNegative.Translation(f.x,f.y); translationPositive = translationPositive.Translation(-4, -4); rotation = rotation.Rotation(f.angleRadians * 180/ PI); CTransform3x3 finalTransformation = translationNegative * rotation * scaleTransform * translationPositive; //CFloatImage sample61x61Window = //CFloatImage pixelWindow = GetXWindowAroundPixel(grayImage, f.x, f.y, 61); WarpGlobal(blurredImage, postHomography, finalTransformation, eWarpInterpLinear, 1.0f); //now we get the 41x41 box around the feature for(int row=0; row< 8; row++) { for(int col=0;col< 8;col++) { f.data.push_back(postHomography.Pixel(col, row, 0)); } } /* // now we do the subsampling first round to reduce to a 20x20 int imgSize = 41; subsample(&f, imgSize, gaussianImage); //second round of subsampling to get it to a 10x10 imgSize = 20; subsample(&f, imgSize, gaussianImage); imgSize = 10; CFloatImage img = featureToImage(f, imgSize, imgSize); CFloatImage blurredImg(img.Shape()); Convolve(img, blurredImg, gaussianImage); featuresFromImage(&f,blurredImg,imgSize,imgSize); int count = 0; for(int y=0; y<imgSize; y++) { for(int x=0; x<imgSize; x++) { if(x == 3 || x == 7 || y == 3 || y == 7) { f.data.erase(f.data.begin() + count); } else { count++; } } } */ normalizeIntensities(&f, 8, 8); featureIterator++; } }
int OKIDriver::InnerRemixBmpInOKI(byte* pBmpData, int bytePerLine, int bmpWidth, int bmpHeight, long lx, long ly, byte* pPrintData, int PrintDataLength) { mBmpWidth = bmpWidth; mBmpHeight = bmpHeight; if (!isGrayData(bmpWidth, bytePerLine)) { //灰度化 mpGrayData = ConvertToGray(pBmpData, bytePerLine, bmpWidth, bmpHeight); } else { mpGrayData = pBmpData; } //二值化 mpBlankInfo = ConvertToBW(mpGrayData, bmpWidth, bmpHeight); delete[] mpGrayData; mpGrayData = nullptr; myxPos = 0; pPrintData[myxPos + 0] = 0x18; pPrintData[myxPos + 1] = 0x0d; pPrintData[myxPos + 2] = 0x1b; pPrintData[myxPos + 3] = 0x36; myxPos += 4; int lYinPix = fabs(ly) * 120.f / 254.f; int icounts = lYinPix / 255; if (ly > 0) { for (int i = 0; i < icounts; ++i) { pPrintData[myxPos + 0] = 0x0d; pPrintData[myxPos + 1] = 0x1b; pPrintData[myxPos + 2] = 0x25; pPrintData[myxPos + 3] = 0x35; pPrintData[myxPos + 4] = 0xff; myxPos += 5; } lYinPix &= 0xff; if (lYinPix > 0 || lYinPix < 0) { pPrintData[myxPos + 0] = 0x0d; pPrintData[myxPos + 1] = 0x1b; pPrintData[myxPos + 2] = 0x25; pPrintData[myxPos + 3] = 0x35; pPrintData[myxPos + 4] = lYinPix; myxPos += 5; } } long height = bmpHeight; int skipLines = 0; byte** DataBlock = 0; long ht = 0; long lXinPix = lx * 180 / 254; while (ht < height) { skipLines = 0; byte tempByte = (byte)(0x80 >> (ht & 0x07)); while ((mpBlankInfo[ht >> 3] & tempByte) && (ht < height)) { ++ht; ++skipLines; } if (skipLines > 0) { int iSkipYpos = skipLines; iSkipYpos = (float)iSkipYpos / 180.f * 120.f; int iSkipCounts = iSkipYpos / 255; for (int i = 0; i < iSkipCounts; ++i) { pPrintData[myxPos + 0] = 0x0d; pPrintData[myxPos + 1] = 0x1b; pPrintData[myxPos + 2] = 0x25; pPrintData[myxPos + 3] = 0x35; pPrintData[myxPos + 4] = 0xff; myxPos += 5; } iSkipYpos &= 0xff; if (iSkipYpos != 0) { pPrintData[myxPos + 0] = 0x0d; pPrintData[myxPos + 1] = 0x1b; pPrintData[myxPos + 2] = 0x25; pPrintData[myxPos + 3] = 0x35; pPrintData[myxPos + 4] = iSkipYpos; myxPos += 5; } } if (ht >= height) { break; } if (lXinPix > 0) { pPrintData[myxPos + 0] = 0x1b; pPrintData[myxPos + 1] = 0x25; pPrintData[myxPos + 2] = 0x36; pPrintData[myxPos + 3] = lXinPix % 256; pPrintData[myxPos + 4] = lXinPix / 256; myxPos += 5; } DataBlock = get24Rows(ht); if (DataBlock == nullptr) { break; } ht += 24; twentyfourPointPerCol(DataBlock, pPrintData, 1); for (long i = 0; i < mBmpWidth; ++i) { delete[] DataBlock[i]; } delete[] DataBlock; } pPrintData[myxPos + 0] = 0x0c; ++myxPos; return myxPos; }
int main(int argc, const char *argv[]) { WebPPicture pic1, pic2; int ret = 1; float disto[5]; size_t size1 = 0, size2 = 0; int type = 0; int c; int help = 0; int keep_alpha = 0; int scale = 0; int use_gray = 0; const char* name1 = NULL; const char* name2 = NULL; const char* output = NULL; if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) { fprintf(stderr, "Can't init pictures\n"); return 1; } for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-ssim")) { type = 1; } else if (!strcmp(argv[c], "-psnr")) { type = 0; } else if (!strcmp(argv[c], "-alpha")) { keep_alpha = 1; } else if (!strcmp(argv[c], "-scale")) { scale = 1; } else if (!strcmp(argv[c], "-gray")) { use_gray = 1; } else if (!strcmp(argv[c], "-h")) { help = 1; ret = 0; } else if (!strcmp(argv[c], "-o")) { if (++c == argc) { fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]); goto End; } output = argv[c]; } else if (name1 == NULL) { name1 = argv[c]; } else { name2 = argv[c]; } } if (help || name1 == NULL || name2 == NULL) { if (!help) { fprintf(stderr, "Error: missing arguments.\n"); } Help(); goto End; } if ((size1 = ReadPicture(name1, &pic1, 1)) == 0) { goto End; } if ((size2 = ReadPicture(name2, &pic2, 1)) == 0) { goto End; } if (!keep_alpha) { WebPBlendAlpha(&pic1, 0x00000000); WebPBlendAlpha(&pic2, 0x00000000); } if (!WebPPictureDistortion(&pic1, &pic2, type, disto)) { fprintf(stderr, "Error while computing the distortion.\n"); goto End; } printf("%u %.2f %.2f %.2f %.2f %.2f\n", (unsigned int)size1, disto[4], disto[0], disto[1], disto[2], disto[3]); if (output != NULL) { uint8_t* data = NULL; size_t data_size = 0; if (pic1.use_argb != pic2.use_argb) { fprintf(stderr, "Pictures are not in the same argb format. " "Can't save the difference map.\n"); goto End; } if (pic1.use_argb) { int n; fprintf(stderr, "max differences per channel: "); for (n = 0; n < 3; ++n) { // skip the alpha channel const int range = (type == 1) ? SSIMScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, 4, pic1.width, pic1.height, scale) : DiffScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, 4, pic1.width, pic1.height, scale); if (range < 0) fprintf(stderr, "\nError computing diff map\n"); fprintf(stderr, "[%d]", range); } fprintf(stderr, "\n"); if (use_gray) ConvertToGray(&pic1); } else { fprintf(stderr, "Can only compute the difference map in ARGB format.\n"); goto End; } data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb, pic1.width, pic1.height, pic1.argb_stride * 4, &data); if (data_size == 0) { fprintf(stderr, "Error during lossless encoding.\n"); goto End; } ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1; WebPFree(data); if (ret) goto End; } ret = 0; End: WebPPictureFree(&pic1); WebPPictureFree(&pic2); return ret; }
// Compute MOPs descriptors. void ComputeMOPSDescriptors(CFloatImage &image, FeatureSet &features) { int w = image.Shape().width; // image width int h = image.Shape().height; // image height // Create grayscale image used for Harris detection CFloatImage grayImage=ConvertToGray(image); // Apply a 7x7 gaussian blur to the grayscale image CFloatImage blurImage(w,h,1); Convolve(grayImage, blurImage, ConvolveKernel_7x7); // Transform matrices CTransform3x3 xform; CTransform3x3 trans1; CTransform3x3 rotate; CTransform3x3 scale; CTransform3x3 trans2; // Declare additional variables float pxl; // pixel value double mean, sq_sum, stdev; // variables for normailizing data set // This image represents the window around the feature you need to compute to store as the feature descriptor const int windowSize = 8; CFloatImage destImage(windowSize, windowSize, 1); for (vector<Feature>::iterator i = features.begin(); i != features.end(); i++) { Feature &f = *i; // Compute the transform from each pixel in the 8x8 image to sample from the appropriate // pixels in the 40x40 rotated window surrounding the feature trans1 = CTransform3x3::Translation(f.x, f.y); // translate window to feature point rotate = CTransform3x3::Rotation(f.angleRadians * 180.0 / PI); // rotate window by angle scale = CTransform3x3::Scale(5.0); // scale window by 5 trans2 = CTransform3x3::Translation(-windowSize/2, -windowSize/2); // translate window to origin // transform resulting from combining above transforms xform = trans1*scale*rotate*trans2; //Call the Warp Global function to do the mapping WarpGlobal(blurImage, destImage, xform, eWarpInterpLinear); // Resize data field for a 8x8 square window f.data.resize(windowSize * windowSize); // Find mean of window mean = 0; for (int y = 0; y < windowSize; y++) { for (int x = 0; x < windowSize; x++) { pxl = destImage.Pixel(x, y, 0); f.data[y*windowSize + x] = pxl; mean += pxl/(windowSize*windowSize); } } // Find standard deviation of window sq_sum = 0; for (int k = 0; k < windowSize*windowSize; k++) { sq_sum += (mean - f.data[k]) * (mean - f.data[k]); } stdev = sqrt(sq_sum/(windowSize*windowSize)); // Normalize window to have 0 mean and unit variance by subtracting // by mean and dividing by standard deviation for (int k = 0; k < windowSize*windowSize; k++) { f.data[k] = (f.data[k]-mean)/stdev; } } }
// Compute Simple descriptors. void ComputeSimpleDescriptors(CFloatImage &image, FeatureSet &features) { // Create grayscale image used for Harris detection CFloatImage grayImage=ConvertToGray(image); int w = grayImage.Shape().width; // image width int h = grayImage.Shape().height; // image height // Declare additional variables int newX, newY; // (x,y) coordinate for pixel in 5x5 sample window int padType = 0; // select variable for what type of padding to use: , 0->zero, 1->edge, 2->reflect // Iterate through feature set and store simple descriptors for each feature into // corresponding feature for (vector<Feature>::iterator i = features.begin(); i != features.end(); i++) { Feature &f = *i; // Set angle to 0 since simple descriptors do not include orientation f.angleRadians = 0; // Resize data field for a 5x5 square window f.data.resize(5 * 5); // The descriptor is a 5x5 window of intensities sampled centered on the feature point for (int j = 0; j < 25; j++) { find5x5Index(f.x,f.y,j,&newX,&newY); if(grayImage.Shape().InBounds(newX, newY)) { f.data[j] = grayImage.Pixel(newX, newY, 0); } else { // Depending on value of padType, perform different types of border padding switch (padType) { case 1: // 1 -> replicate border values if (newX < 0) { newX = 0; } else if (newX >= w) { newX = w-1; } if (newY < 0) { newY = 0; } else if (newY >= h) { newY = h-1; } f.data[j] = grayImage.Pixel(newX, newY, 0); break; case 2: // 2 -> reflect border pixels if (newX < 0) { newX = -newX; } else if (newX >= w) { newX = w-(newX%w)-1; } if (newY < 0) { newY = -newY; } else if (newY >= h) { newY = h-(newY%h)-1; } f.data[j] = grayImage.Pixel(newX, newY, 0); break; default: // 0 -> zero padding f.data[j] = 0; break; } } } } }