optical character recognisation

This commit is contained in:
Anshul Maheshwari
2014-06-08 01:15:32 +05:30
parent 48c15d7828
commit dc8a05d76a
6 changed files with 199 additions and 43 deletions

55
docs/OCR.txt Normal file
View File

@@ -0,0 +1,55 @@
Overview
========
OCR (Optical Character Recognisation ) is an technique used to
extract text from images. In the World of Subtile, subtitle stored
in bitmap format are common and even neccassary. for converting subtile
in bitmap format to subtilte in text format ocr is used.
Dependecy
=========
Tesseract (OCR library by google)
Leptonica (image processing library)
How to compile ccextractor on linux with OCR
=============================================
Download and Install Leptonnica.
-------------------------------
This package is available, you need liblept-devel library.
If Leptonica isn't available for your distribution, or you want to use a newer version
than they offer, you can compile your own.
you can download lib leptonica from http://www.leptonica.com/download.html
Download and Install Tesseract.
-------------------------------
Tesseract is available directly from many Linux distributions. The package is generally
called 'tesseract' or 'tesseract-ocr' - search your distribution's repositories to
find it. Packages are also generally available for language training data (search the
repositories,) but if not you will need to download the appropriate training data,
unpack it, and copy the .traineddata file into the 'tessdata' directory, probably
/usr/share/tesseract-ocr/tessdata or /usr/share/tessdata.
If Tesseract isn't available for your distribution, or you want to use a newer version
than they offer, you can compile your own.
If you compile Tesseract then following command in its source code are enough
./autogen.sh
./configure
make
sudo make install
sudo ldconfig
Note:
1) CCExtractor is tested with Tesseract 3.02.02 version.
you can download tesseract from https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing
Compile CCextractor passing flags like following
-------------------------------------------------
make ENABLE_OCR=yes

View File

@@ -35,6 +35,11 @@ INSTLALL = cp -f -p
INSTLALL_PROGRAM = $(INSTLALL)
DESTDIR = /usr/bin
ifeq ($(ENABLE_OCR),yes)
CFLAGS+=-I/usr/local/include/tesseract -I/usr/local/include/leptonica
CFLAGS+=-DENABLE_OCR
LDFLAGS+= $(shell pkg-config --libs tesseract)
endif
.PHONY: all
all: objs_dir $(TARGET)

View File

@@ -33,6 +33,7 @@
#include "dvb_subtitle_decoder.h"
#include "spupng_encoder.h"
#include "ocr.h"
#define DEBUG
#ifdef DEBUG
@@ -255,9 +256,17 @@ int mapclut_paletee(png_color *palette, png_byte *alpha, uint32_t *clut,
}
return 0;
}
/*
* @param alpha out
* @param intensity in
* @param palette out should be already initialized
* @param bitmap in
* @param size in size of bitmap
* @param max_color in
* @param nb_color in
*/
int quantize_map(png_byte *alpha, uint8_t *intensity, png_color *palette,
uint8_t *bitmap, int h, int w, int max_color, int nb_color)
uint8_t *bitmap, int size, int max_color, int nb_color)
{
/*
* occurrence of color in image
@@ -301,12 +310,9 @@ int quantize_map(png_byte *alpha, uint8_t *intensity, png_color *palette,
memset(mcit, 0, nb_color * sizeof(uint32_t));
/* calculate histogram of image */
for (int i = 0; i < h; i++)
for (int i = 0; i < size; i++)
{
for (int j = 0; j < w; j++)
{
histogram[bitmap[i * w + (j)]]++;
}
histogram[bitmap[i]]++;
}
sort_intensity_wise((uint8_t*) alpha, (uint8_t*) intensity, iot, nb_color);
@@ -365,8 +371,53 @@ int quantize_map(png_byte *alpha, uint8_t *intensity, png_color *palette,
freep(&iot);
return ret;
}
static int pre_process_bitmap(png_color **palette, png_byte **alpha, int size,
uint32_t *clut, uint8_t *luit, uint8_t *bitmap, uint8_t depth)
{
/*local pointer to palette */
png_color *lpalette = NULL;
/* local pointer to alpha */
png_byte *lalpha = NULL;
int nb_color = (1<< depth);
int ret = 0;
lpalette = (png_color*) malloc(nb_color * sizeof(png_color));
if(!lpalette)
{
ret = -1;
goto end;
}
lalpha = (png_byte*) malloc(nb_color * sizeof(png_byte));
if(!lalpha)
{
ret = -1;
goto end;
}
if(clut)
mapclut_paletee(lpalette, lalpha, clut, nb_color);
else
{
/* initialize colors with white */
memset(palette,0xff,sizeof(nb_color * sizeof(*lpalette)));
/* initialize transparency as complete transparent */
memset(lalpha,0,sizeof(nb_color * sizeof(*lalpha)));
}
if(bitmap)
{
quantize_map(lalpha, luit, lpalette, bitmap, size, 3, nb_color);
}
*palette = lpalette;
*alpha = lalpha;
end:
return ret;
}
static int save_spupng(const char *filename, uint8_t *bitmap, int w, int h,
uint32_t *clut, uint8_t *luit,uint8_t depth)
png_color *palette, png_byte *alpha, int nb_color)
{
FILE *f = NULL;
png_structp png_ptr = NULL;
@@ -374,43 +425,11 @@ static int save_spupng(const char *filename, uint8_t *bitmap, int w, int h,
png_bytep* row_pointer = NULL;
int i, j, ret;
int k = 0;
png_color *palette = NULL;
png_byte *alpha = NULL;
int nb_color = (1<< depth);
if(!h)
h = 1;
if(!w)
w = 1;
palette = (png_color*) malloc(nb_color * sizeof(png_color));
if(!palette)
{
ret = -1;
goto end;
}
alpha = (png_byte*) malloc(nb_color * sizeof(png_byte));
if(!alpha)
{
ret = -1;
goto end;
}
if(clut)
mapclut_paletee(palette, alpha, clut, nb_color);
else
{
/* initialize colors with white */
memset(palette,0xff,sizeof(nb_color * sizeof(*palette)));
/* initialize transparency as complete transparent */
memset(alpha,0,sizeof(nb_color * sizeof(*alpha)));
}
if(bitmap)
quantize_map(alpha, luit, palette, bitmap, h, w, 3, nb_color);
f = fopen(filename, "wb");
if (!f)
@@ -791,6 +810,11 @@ static void save_display_set(DVBSubContext *ctx)
if (x_pos >= 0)
{
png_color *palette = NULL;
png_byte *alpha = NULL;
#ifdef ENABLE_OCR
char*str = NULL;
#endif
filename = get_spupng_filename(sp);
inc_spupng_fileindex(sp);
@@ -821,17 +845,28 @@ static void save_display_set(DVBSubContext *ctx)
}
}
save_spupng(filename, pbuf, width, height,
clut->clut16, clut->ilut16,region->depth);
pre_process_bitmap(&palette,&alpha,width*height,clut->clut16, clut->ilut16,pbuf,region->depth);
#ifdef ENABLE_OCR
str = ocr_bitmap(palette,alpha,pbuf,width,height);
if(str)
{
write_spucomment(sp,str);
}
#endif
save_spupng(filename, pbuf, width, height, palette, alpha,(1 << region->depth));
free(pbuf);
freep(&palette);
freep(&alpha);
}
else if(!ctx->prev_start)
{
png_color palette = {0,0,0};
png_byte alpha = 0;
filename = get_spupng_filename(sp);
inc_spupng_fileindex(sp);
/* save dummy frame */
save_spupng(filename,NULL,1,1,NULL,NULL,0);
save_spupng(filename,NULL,1,1,&palette,&alpha,1);
}

View File

@@ -86,6 +86,7 @@ int parse_dvb_description(struct dvb_config* cfg, unsigned char*data,
*
*/
void dvbsub_set_write(void *dvb_ctx, struct ccx_s_write *out);
#ifdef __cplusplus
}
#endif

54
src/ocr.c Normal file
View File

@@ -0,0 +1,54 @@
#include "png.h"
#ifdef ENABLE_OCR
#include "capi.h"
#include "allheaders.h"
char* ocr_bitmap(png_color *palette,png_byte *alpha, unsigned char* indata,int w, int h)
{
TessBaseAPI* api;
PIX *pix;
char*text_out= NULL;
int i,j,index,ret;
unsigned int wpl;
unsigned int *data,*ppixel;
api = TessBaseAPICreate();
pix = pixCreate(w, h, 32);
if(pix == NULL)
{
return NULL;
}
wpl = pixGetWpl(pix);
data = pixGetData(pix);
pixSetSpp(pix, 4);
for (i = 0; i < h; i++)
{
ppixel = data + i * wpl;
for (j = 0; j < w; j++)
{
index = indata[i * w + (j)];
composeRGBPixel(palette[index].red, palette[index].green,palette[index].blue, ppixel);
SET_DATA_BYTE(ppixel, L_ALPHA_CHANNEL,alpha[index]);
ppixel++;
}
}
ret = TessBaseAPIInit3(api,"", "eng");
if(ret < 0)
{
return NULL;
}
//text_out = TessBaseAPIProcessPages(api, "/home/anshul/test_videos/dvbsubtest.d/sub0018.png", 0, 0);
text_out = TessBaseAPIProcessPage(api, pix, 0, NULL, NULL, 1000);
if(!text_out)
printf("\nsomething messy\n");
return text_out;
}
#else
char* ocr_bitmap(png_color *palette,png_byte *alpha, unsigned char* indata,unsigned char d,int w, int h)
{
mprint("ocr not supported without tesseract\n");
return NULL;
}
#endif

6
src/ocr.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef OCR_H
#define OCR_H
#include <png.h>
char* ocr_bitmap(png_color *palette,png_byte *alpha, unsigned char* indata,int w, int h);
#endif