mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-09-25 00:04:51 +00:00
optical character recognisation
This commit is contained in:
55
docs/OCR.txt
Normal file
55
docs/OCR.txt
Normal 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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
54
src/ocr.c
Normal 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
|
||||
Reference in New Issue
Block a user