PIX * PixTest1(PIX *pixs, l_int32 size, l_float32 factor, L_REGPARAMS *rp) { l_int32 w, h; PIX *pixm, *pixsd, *pixth, *pixd, *pixt; PIXA *pixa; pixm = pixsd = pixth = pixd = NULL; pixGetDimensions(pixs, &w, &h, NULL); /* Get speed */ startTimer(); pixSauvolaBinarize(pixs, size, factor, 1, NULL, NULL, NULL, &pixd); fprintf(stderr, "\nSpeed: 1 tile, %7.3f Mpix/sec\n", (w * h / 1000000.) / stopTimer()); pixDestroy(&pixd); /* Get results */ pixSauvolaBinarize(pixs, size, factor, 1, &pixm, &pixsd, &pixth, &pixd); pixa = pixaCreate(0); pixSaveTiled(pixm, pixa, 1, 1, 30, 8); pixSaveTiled(pixsd, pixa, 1, 0, 30, 8); pixSaveTiled(pixth, pixa, 1, 1, 30, 8); pixSaveTiled(pixd, pixa, 1, 0, 30, 8); pixt = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixt, IFF_JFIF_JPEG); if (rp->index < 5) pixDisplayWithTitle(pixt, 100, 100, NULL, rp->display); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixaDestroy(&pixa); pixDestroy(&pixm); pixDestroy(&pixsd); pixDestroy(&pixth); pixDestroy(&pixt); return pixd; }
void _display_frame(struct lib_hardsubx_ctx *ctx, AVFrame *frame, int width, int height, int timestamp) { // Debug: Display the frame after processing PIX *im; im = pixCreate(width,height,32); PIX *hue_im = pixCreate(width,height,32); int i,j; for(i=0;i<height;i++) { for(j=0;j<width;j++) { int p=j*3+i*frame->linesize[0]; int r=frame->data[0][p]; int g=frame->data[0][p+1]; int b=frame->data[0][p+2]; pixSetRGBPixel(im,j,i,r,g,b); float H,S,V; rgb_to_hsv((float)r,(float)g,(float)b,&H,&S,&V); if(abs(H-ctx->hue)<20) { pixSetRGBPixel(hue_im,j,i,r,g,b); } } } PIX *edge_im = pixCreate(width,height,8),*edge_im_2 = pixCreate(width,height,8); edge_im = pixConvertRGBToGray(im,0.0,0.0,0.0); edge_im = pixSobelEdgeFilter(edge_im, L_VERTICAL_EDGES); edge_im = pixDilateGray(edge_im, 21, 1); edge_im = pixThresholdToBinary(edge_im,50); PIX *pixd = pixCreate(width,height,1); pixSauvolaBinarize(pixConvertRGBToGray(hue_im,0.0,0.0,0.0), 15, 0.3, 1, NULL, NULL, NULL, &pixd); edge_im_2 = pixConvertRGBToGray(hue_im,0.0,0.0,0.0); edge_im_2 = pixDilateGray(edge_im_2, 5, 5); PIX *feat_im = pixCreate(width,height,32); for(i=3*(height/4);i<height;i++) { for(j=0;j<width;j++) { unsigned int p1,p2,p3,p4; pixGetPixel(edge_im,j,i,&p1); pixGetPixel(pixd,j,i,&p2); // pixGetPixel(hue_im,j,i,&p3); pixGetPixel(edge_im_2,j,i,&p4); if(p1==0&&p2==0&&p4>0)//if(p4>0&&p1==0)//if(p2==0&&p1==0&&p3>0) { pixSetRGBPixel(feat_im,j,i,255,255,255); } } } char *txt=NULL; // txt = get_ocr_text_simple(ctx, feat_im); // txt=get_ocr_text_wordwise_threshold(ctx, feat_im, ctx->conf_thresh); // if(txt != NULL)printf("%s\n", txt); pixDestroy(&im); pixDestroy(&edge_im); pixDestroy(&feat_im); pixDestroy(&edge_im_2); pixDestroy(&pixd); }
char *_process_frame_color_basic(struct lib_hardsubx_ctx *ctx, AVFrame *frame, int width, int height, int index) { char *subtitle_text=NULL; PIX *im; im = pixCreate(width,height,32); PIX *hue_im = pixCreate(width,height,32); int i,j; for(i=0;i<height;i++) { for(j=0;j<width;j++) { int p=j*3+i*frame->linesize[0]; int r=frame->data[0][p]; int g=frame->data[0][p+1]; int b=frame->data[0][p+2]; pixSetRGBPixel(im,j,i,r,g,b); float H,S,V; rgb_to_hsv((float)r,(float)g,(float)b,&H,&S,&V); if(abs(H-ctx->hue)<20) { pixSetRGBPixel(hue_im,j,i,r,g,b); } } } PIX *edge_im = pixCreate(width,height,8),*edge_im_2 = pixCreate(width,height,8); edge_im = pixConvertRGBToGray(im,0.0,0.0,0.0); edge_im = pixSobelEdgeFilter(edge_im, L_VERTICAL_EDGES); edge_im = pixDilateGray(edge_im, 21, 1); edge_im = pixThresholdToBinary(edge_im,50); PIX *pixd = pixCreate(width,height,1); pixSauvolaBinarize(pixConvertRGBToGray(hue_im,0.0,0.0,0.0), 15, 0.3, 1, NULL, NULL, NULL, &pixd); edge_im_2 = pixConvertRGBToGray(hue_im,0.0,0.0,0.0); edge_im_2 = pixDilateGray(edge_im_2, 5, 5); PIX *feat_im = pixCreate(width,height,32); for(i=3*(height/4);i<height;i++) { for(j=0;j<width;j++) { unsigned int p1,p2,p3,p4; pixGetPixel(edge_im,j,i,&p1); pixGetPixel(pixd,j,i,&p2); // pixGetPixel(hue_im,j,i,&p3); pixGetPixel(edge_im_2,j,i,&p4); if(p1==0&&p2==0&&p4>0)//if(p4>0&&p1==0)//if(p2==0&&p1==0&&p3>0) { pixSetRGBPixel(feat_im,j,i,255,255,255); } } } if(ctx->detect_italics) { ctx->ocr_mode = HARDSUBX_OCRMODE_WORD; } // TESSERACT OCR FOR THE FRAME HERE switch(ctx->ocr_mode) { case HARDSUBX_OCRMODE_WORD: if(ctx->conf_thresh > 0) subtitle_text = get_ocr_text_wordwise_threshold(ctx, feat_im, ctx->conf_thresh); else subtitle_text = get_ocr_text_wordwise(ctx, feat_im); break; case HARDSUBX_OCRMODE_LETTER: if(ctx->conf_thresh > 0) subtitle_text = get_ocr_text_letterwise_threshold(ctx, feat_im, ctx->conf_thresh); else subtitle_text = get_ocr_text_letterwise(ctx, feat_im); break; case HARDSUBX_OCRMODE_FRAME: if(ctx->conf_thresh > 0) subtitle_text = get_ocr_text_simple_threshold(ctx, feat_im, ctx->conf_thresh); else subtitle_text = get_ocr_text_simple(ctx, feat_im); break; default: fatal(EXIT_MALFORMED_PARAMETER,"Invalid OCR Mode"); } pixDestroy(&feat_im); pixDestroy(&im); pixDestroy(&edge_im); pixDestroy(&hue_im); return subtitle_text; }
/*! * pixSauvolaBinarizeTiled() * * Input: pixs (8 bpp grayscale, not colormapped) * whsize (window half-width for measuring local statistics) * factor (factor for reducing threshold due to variance; >= 0) * nx, ny (subdivision into tiles; >= 1) * &pixth (<optional return> Sauvola threshold values) * &pixd (<optional return> thresholded image) * Return: 0 if OK, 1 on error * * Notes: * (1) The window width and height are 2 * @whsize + 1. The minimum * value for @whsize is 2; typically it is >= 7.. * (2) For nx == ny == 1, this defaults to pixSauvolaBinarize(). * (3) Why a tiled version? * (a) Because the mean value accumulator is a uint32, overflow * can occur for an image with more than 16M pixels. * (b) The mean value accumulator array for 16M pixels is 64 MB. * The mean square accumulator array for 16M pixels is 128 MB. * Using tiles reduces the size of these arrays. * (c) Each tile can be processed independently, in parallel, * on a multicore processor. * (4) The Sauvola threshold is determined from the formula: * t = m * (1 - k * (1 - s / 128)) * See pixSauvolaBinarize() for details. */ l_int32 pixSauvolaBinarizeTiled(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 nx, l_int32 ny, PIX **ppixth, PIX **ppixd) { l_int32 i, j, w, h, xrat, yrat; PIX *pixth, *pixd, *tileth, *tiled, *pixt; PIX **ptileth, **ptiled; PIXTILING *pt; PROCNAME("pixSauvolaBinarizeTiled"); if (!ppixth && !ppixd) return ERROR_INT("no outputs", procName, 1); if (ppixth) *ppixth = NULL; if (ppixd) *ppixd = NULL; if (!pixs || pixGetDepth(pixs) != 8) return ERROR_INT("pixs undefined or not 8 bpp", procName, 1); if (pixGetColormap(pixs)) return ERROR_INT("pixs is cmapped", procName, 1); pixGetDimensions(pixs, &w, &h, NULL); if (whsize < 2) return ERROR_INT("whsize must be >= 2", procName, 1); if (w < 2 * whsize + 3 || h < 2 * whsize + 3) return ERROR_INT("whsize too large for image", procName, 1); if (factor < 0.0) return ERROR_INT("factor must be >= 0", procName, 1); if (nx <= 1 && ny <= 1) return pixSauvolaBinarize(pixs, whsize, factor, 1, NULL, NULL, ppixth, ppixd); /* Test to see if the tiles are too small. The required * condition is that the tile dimensions must be at least * (whsize + 2) x (whsize + 2). */ xrat = w / nx; yrat = h / ny; if (xrat < whsize + 2) { nx = w / (whsize + 2); L_WARNING("tile width too small; nx reduced to %d\n", procName, nx); } if (yrat < whsize + 2) { ny = h / (whsize + 2); L_WARNING("tile height too small; ny reduced to %d\n", procName, ny); } if (nx <= 1 && ny <= 1) return pixSauvolaBinarize(pixs, whsize, factor, 1, NULL, NULL, ppixth, ppixd); /* We can use pixtiling for painting both outputs, if requested */ if (ppixth) { pixth = pixCreateNoInit(w, h, 8); *ppixth = pixth; } if (ppixd) { pixd = pixCreateNoInit(w, h, 1); *ppixd = pixd; } pt = pixTilingCreate(pixs, nx, ny, 0, 0, whsize + 1, whsize + 1); pixTilingNoStripOnPaint(pt); /* pixSauvolaBinarize() does the stripping */ for (i = 0; i < ny; i++) { for (j = 0; j < nx; j++) { pixt = pixTilingGetTile(pt, i, j); ptileth = (ppixth) ? &tileth : NULL; ptiled = (ppixd) ? &tiled : NULL; pixSauvolaBinarize(pixt, whsize, factor, 0, NULL, NULL, ptileth, ptiled); if (ppixth) { /* do not strip */ pixTilingPaintTile(pixth, i, j, tileth, pt); pixDestroy(&tileth); } if (ppixd) { pixTilingPaintTile(pixd, i, j, tiled, pt); pixDestroy(&tiled); } pixDestroy(&pixt); } } pixTilingDestroy(&pt); return 0; }