/*! \fn int gaussPGM(Pgm* pgmIn, Pgm* pgmOut, double sigma, int dim) * \brief Gaussian blur of an image \a pgmIn. * * Apply as a filter two 1D Gaussian filters with the same \a sigma and matrix linear dimension \a dim. * \param pgmIn Pointer to the input Pgm image structure. * \param pgmOut Pointer to the output Pgm image structure. * \param sigma The sigma of the gaussians. * \param dim The dimension of the gaussian filter. If 0 it will default to the nearest odd value close to 6 sigma. * \return 0 on success, -1 if either pgmIn or pgmOut are NULL. */ int gaussPGM(Pgm* pgmIn, Pgm* pgmOut, double sigma, int dim) { if(!pgmIn) { fprintf(stderr, "Error! No input data. Please Check.\n"); return -1; } if(!pgmOut) { fprintf(stderr, "Error! No space to store the result. Please Check.\n"); return -1; } Filter* filter; Pgm* imgOut1 = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); // linear X guassian filter filter = gauss1DXFilter(sigma, dim); convolution1DXPGM(pgmIn, imgOut1, filter); freeFilter(&filter); // linear Y guassian filter filter = gauss1DYFilter(sigma, dim); convolution1DYPGM(imgOut1, pgmOut, filter); freeFilter(&filter); freePGM(&imgOut1); return 0; }
/*! \fn cedPGM(Pgm* pgmIn, Pgm* pgmOut, double sigma, int dim, int threshold_low, int threshold_high) * \brief Filter the image \a pgmIn with two Prewitt filters alogn the vertical and horizontal direction. * Returns either the magnitute or the phase based on \a phase. * * Apply the vertical and horizontal Prewitt filters and returns the magnitute if \a phase is 0 * or the phase if \a phase is 1. * \param pgmIn Pointer to the input PGM image structure. * \param pgmOut Pointer to the output PGM image structure. * \param sigma The external sigma of the DoG filter. The internal sigma is set to \a sigma / 1.66 . * \param dim The rows and columns of the DoG filter. If set to 0 then it will be the smallest odd next to 6 \a sigma. * \param threshold_low Lower threshold used by the Canny algorithm. * \param threshold_high Hihger threshold used by the Canny algorithm. * \return 0 on success, -1 if either pgmIn or pgmOut are NULL. */ int cedPGM(Pgm* pgmIn, Pgm* pgmOut, double sigma, int dim, int threshold_low, int threshold_high) { int i; Pgm* imgOutX = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); Pgm* imgOutY = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); Pgm* imgOutMod = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); Pgm* imgOutPhi = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); gaussPGM(pgmIn, pgmOut, sigma, dim); Filter* gx = sobelXFilter(); Filter* gy = sobelYFilter(); convolution2DPGM(pgmOut, imgOutX, gx); convolution2DPGM(pgmOut, imgOutY, gy); modulePGM(imgOutX, imgOutY, imgOutMod); phasePGM(imgOutX, imgOutY, imgOutPhi); resetPGM(pgmOut); suppressionPGM(imgOutMod, imgOutPhi, pgmOut); freePGM(&imgOutX); freePGM(&imgOutY); freePGM(&imgOutMod); freePGM(&imgOutPhi); // Find strong and weak edges with thresholding Pgm *imgNH = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); thresholdPGM(pgmOut, imgNH, threshold_high); Pgm *imgNLshadow = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); thresholdPGM(pgmOut, imgNLshadow, threshold_low); Pgm *imgNL = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); linearAddPGM(imgNLshadow, imgNH, 1.0, -1.0, imgNL); int change = 1; // Find 8-connected pixels in imgNL by a repeated search for (i=0; (i<50) && change; i++) { connectivityPGM(imgNH, imgNL, pgmOut); change = comparePGM(imgNH, pgmOut); copyPGM(pgmOut, imgNH); } copyPGM(imgNH, pgmOut); freePGM(&imgNLshadow); freePGM(&imgNH); freePGM(&imgNL); return 0; }
/*! \fn int prewittPGM(Pgm* pgmIn, Pgm* pgmOut, uint8_t phase) * \brief Filter the image \a pgmIn with two Prewitt filters alogn the vertical and horizontal direction. * Returns either the magnitute or the phase based on \a phase. * * Apply the vertical and horizontal Prewitt filters and returns the magnitute if \a phase is 0 * or the phase if \a phase is 1. * \param pgmIn Pointer to the input PGM image structure. * \param pgmOut Pointer to the output PGM image structure. * \param phase Returns the phase if set to 1. Otherwise it returns the magnitude. * \return 0 on success, -1 if either pgmIn or pgmOut are NULL. */ int prewittPGM(Pgm* pgmIn, Pgm* pgmOut, unsigned int phase) { if(!pgmIn) { fprintf(stderr, "Error! No input data. Please Check.\n"); return -1; } if(!pgmOut) { fprintf(stderr, "Error! No space to store the result. Please Check.\n"); return -1; } Filter* filter; Pgm* gx = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); // apply a sobel horizontal filter filter = prewittXFilter(); convolution2DPGM(pgmIn, gx, filter); freeFilter(&filter); Pgm* gy = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); // apply a sobel vertical filter filter = prewittYFilter(); convolution2DPGM(pgmIn, gy, filter); freeFilter(&filter); // compute the module of the two images with the // applied sobel filters resetPGM(pgmOut); if (phase == 0) { modulePGM(gx, gy, pgmOut); } else phasePGM(gx, gy, pgmOut); freePGM(&gx); freePGM(&gy); return 0; }
/*! \fn execImageOps(Pgm *pgmIn, Pgm* pgmOut, FILE *fp) * \brief Filter the image \a pgmIn with the filters listed in file \a fp. * * The file \a fp contains a list of filters, one per line, that will be applied in sequence to * the image pointed by \a pgmIn. The output will be stored in the Pgm structure pointed by * \a pgmOut. Certain filters have optional parameters. * * \param pgmIn Pointer to the input PGM image structure. * \param pgmOut Pointer to the output PGM image structure. * \param fp Pointer to a file with the list of filters. * * \par List of implemented filters * * - threshold [threshold_value (default 0)] * - uniform_noise [range_value (default 32)] * - salt_n_pepper [density (default 0.05)] * - normalize * - equalize * - median * - average * - internal_contour * - operator_39 * - nagao * - sharpening * - prewitt [mod|phase (default mod)] * - sobel [mod|phase (default mod)] * - gauss [sigma (default 1)] [dim (default 0)] * - dog [sigma (default 1)] [dim (default 0)] * - ced [sigma (default sqrt(2))] [threshold (default 25)] */ void execImageOps(Pgm *pgmIn, Pgm* pgmOut, FILE *fp) { char buffer[64]; char *ch, *cmdline; int iarg; float farg; Pgm* pgmTmp = newPGM(pgmIn->width, pgmIn->height, pgmIn->max_val); copyPGM(pgmIn, pgmOut); while (fgets(buffer,sizeof(buffer),fp)!=NULL) { copyPGM(pgmOut, pgmTmp); // Read a line till \n or 64 char cmdline = trimwhitespace(buffer); ch = strtok(cmdline, " "); if (strcmp(ch,"threshold")==0) { ch = strtok(NULL, " "); if (ch == NULL) { iarg = 0; } else iarg = atoi(ch); thresholdPGM(pgmTmp, pgmOut, iarg); } else if (strcmp(ch,"uniform_noise")==0) { ch = strtok(NULL, " "); if (ch == NULL) { iarg = 32; } else iarg = atoi(ch); addUniformNoisePGM(pgmTmp, pgmOut, iarg); } else if (strcmp(ch,"salt_n_pepper")==0) { ch = strtok(NULL, " "); if (ch == NULL) { farg = 0.05; } else sscanf(ch,"%f",&farg); addSaltPepperNoisePGM(pgmTmp, pgmOut, farg); } else if (strcmp(ch,"normalize")==0) { normalizePGM(pgmTmp, pgmOut); } else if (strcmp(ch,"equalize")==0) { equalizePGM(pgmTmp, pgmOut); } else if (strcmp(ch,"median")==0) { fprintf(stderr,"Start median\n"); medianPGM(pgmTmp, pgmOut); fprintf(stderr,"Median completed\n"); } else if (strcmp(ch,"average")==0) { averagePGM(pgmTmp, pgmOut); } else if (strcmp(ch,"internal_contour")==0) { contourN8IntPGM(pgmTmp, pgmOut); } else if (strcmp(ch,"operator_39")==0) { op39PGM(pgmTmp, pgmOut); } else if (strcmp(ch,"nagao")==0) { nagaoPGM(pgmTmp, pgmOut); } else if (strcmp(ch,"sharpening")==0) { sharpeningPGM(pgmTmp, pgmOut); } else if (strcmp(ch, "prewitt")==0) { ch = strtok(NULL, " "); if (ch==NULL) { iarg = 0; } else if (strcmp(ch, "phase") == 0) { iarg = 1; } else iarg = 0; prewittPGM(pgmTmp, pgmOut, iarg); } else if (strcmp(ch, "sobel")==0) { ch = strtok(NULL, " "); if (ch==NULL) { iarg = 0; } else if (strcmp(ch, "phase") == 0) { iarg = 1; } else iarg = 0; sobelPGM(pgmTmp, pgmOut, iarg); } else if (strcmp(ch, "gauss")==0) { ch = strtok(NULL, " "); if (ch==NULL) { farg = 1.0; iarg = 0; } else sscanf(ch, "%f", &farg); ch = strtok(NULL, " "); if ( ch == NULL) { iarg = 0; } else iarg = atoi(ch); gaussPGM(pgmTmp, pgmOut, farg, iarg); } else if (strcmp(ch, "dog")==0) { ch = strtok(NULL, " "); if (ch==NULL) { farg = 1.0; iarg = 0; } else sscanf(ch, "%f", &farg); ch = strtok(NULL, " "); if ( ch == NULL) { iarg = 0; } else iarg = atoi(ch); dogPGM(pgmTmp, pgmOut, farg, iarg); } else if (strcmp(ch, "ced")==0) { ch = strtok(NULL, " "); if (ch==NULL) { farg = sqrt(2.0); iarg = 0; } else sscanf(ch, "%f", &farg); ch = strtok(NULL, " "); if ( ch == NULL) { iarg = 25; } else iarg = atoi(ch); cedPGM(pgmTmp, pgmOut, farg, 0, iarg, iarg*3); } } freePGM(&pgmTmp); return; }
int main(int argc, char *argv[]) { imagePGM srcImg; imagePGM dstImg; char *srcFilename; char *dstFilename; int FileLoad = 0, FileLoadFilename = 0, FileSave = 0, FileSaveFilename = 0, flagInfo = 0, FileInfoOptions = 0; int FileImage = 0, FileImageOptions = 0, rotAngle = 0; int c; int index; while ((c = getopt(argc, argv, "i:o:hnr:")) != -1) { switch (c) { case 'h': printHelp(); exit(EXIT_SUCCESS); case 'n': flagInfo = 1; break; case 'i': FileLoad = 1; FileLoadFilename = 1; srcFilename = optarg; break; case 'o': FileSave = 1; FileSaveFilename = 1; dstFilename = optarg; break; case 'r': FileImage = 1; FileImageOptions = 1; rotAngle = atoi(optarg); break; case '?': break; /* if (optopt == 'i') fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (optopt == 'o') fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (optopt == 'r') fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (isprint(optopt)) fprintf(stderr, "Unknown option `-%c'.\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; */ default: fprintf(stderr, "Wrong arguments. try simpleocr -h for help."); exit(EXIT_FAILURE); } } ///printf("src = %s\n", dstFilename); if (FileLoad && FileLoadFilename) { srcImg = loadPGM(srcFilename); if (flagInfo) { printf ("Properties:\n"); printf ("format: %s\n", getFormatPGM(srcImg)); printf ("depth: %d\n", getMaxIntensityPGM(srcImg)); printf ("width: %d\n", getColsPGM(srcImg)); printf ("height: %d\n", getRowsPGM(srcImg)); printf ("###: %d\n", getRowsPGM(srcImg)); dstImg = buildHistogram(srcImg); savePGM("histogram.pgm", dstImg); } } if (FileSave && FileSaveFilename) { if (FileImage) { dstImg = rotatePGM(srcImg, rotAngle); } savePGM(dstFilename, dstImg); freePGM(dstImg); printf ("Done\n"); } return 0; }