diff --git a/bazaar/PixRaster/Lept-PageSeg.cpp b/bazaar/PixRaster/Lept-PageSeg.cpp index 4f5b3174a..8e22fcd09 100644 --- a/bazaar/PixRaster/Lept-PageSeg.cpp +++ b/bazaar/PixRaster/Lept-PageSeg.cpp @@ -29,4 +29,71 @@ bool PixRaster::GetRegionsBinary(int page) } +/* +// text baseline finding routine +Array PixRaster::FindBaselines(int page) +{ + PTA *pta; + NUMA *numa; + int res; + l_int32 x, y; + Array ptArray; + + if(IsEmpty()) + return Array(); + page = getTruePage(page); + + PIX *pix = pixaGetPix(pixa, page, L_CLONE); + numa = pixFindBaselines(pix, &pta, 0); + pixDestroy(&pix); + if(!numa || !pta) + return Array(); + for(int iPoint = 0; iPoint < ptaGetCount(pta); iPoint++) + { + res = ptaGetIPt(pta, iPoint, &x, &y); + if(res) + { + numaDestroy(&numa); + ptaDestroy(&pta); + return Array(); + } + ptArray.Add(Point(x, y)); + } + numaDestroy(&numa); + ptaDestroy(&pta); + return ptArray; +} +*/ + +// text baseline finding routine +Array PixRaster::FindBaselines(int page) +{ + NUMA *numa; + int res; + l_int32 y; + Array intArray; + + if(IsEmpty()) + return Array(); + page = getTruePage(page); + + PIX *pix = pixaGetPix(pixa, page, L_CLONE); + numa = pixFindBaselines(pix, NULL, 0); + pixDestroy(&pix); + if(!numa) + return Array(); + for(int iLine = 0; iLine < numaGetCount(numa); iLine++) + { + res = numaGetIValue(numa, iLine, &y); + if(res) + { + numaDestroy(&numa); + return Array(); + } + intArray.Add(y); + } + numaDestroy(&numa); + return intArray; +} + END_UPP_NAMESPACE diff --git a/bazaar/PixRaster/Lept-Skew.cpp b/bazaar/PixRaster/Lept-Skew.cpp index e699d54ff..fd3c1d945 100644 --- a/bazaar/PixRaster/Lept-Skew.cpp +++ b/bazaar/PixRaster/Lept-Skew.cpp @@ -110,4 +110,22 @@ bool PixRaster::FindSkewSweepAndSearch( } +bool PixRaster::DeskewLocal(int page) +{ + if(IsEmpty()) + return false; + page = getTruePage(page); + + PIX *sPix = pixaGetPix(pixa, page, L_CLONE); + PIX *dPix = pixDeskewLocal(sPix, 0, 0, 0, 0.0, 0.0, 0.0); + pixDestroy(&sPix); + if(!dPix) + return false; + AddPIX(dPix, PIXRASTER_CLONE); + SeekPage(PIXRASTER_LASTPAGE); + pixDestroy(&dPix); + return true; +} + + END_UPP_NAMESPACE diff --git a/bazaar/PixRaster/PixRaster.h b/bazaar/PixRaster/PixRaster.h index adb902683..519c83630 100644 --- a/bazaar/PixRaster/PixRaster.h +++ b/bazaar/PixRaster/PixRaster.h @@ -238,6 +238,8 @@ class PixRaster : public Raster double minbsdelta, int page = PIXRASTER_CURPAGE); + bool DeskewLocal(int page = PIXRASTER_CURPAGE); + // NOTE : Leptonica has many more skew functions.... //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -276,6 +278,8 @@ class PixRaster : public Raster // top level page segmenting bool GetRegionsBinary(int page = PIXRASTER_CURPAGE) ; + // text baseline finding routine + Array FindBaselines(int page = PIXRASTER_CURPAGE); }; // END class PixRaster diff --git a/bazaar/TestLeptonica/BaseLine.cpp b/bazaar/TestLeptonica/BaseLine.cpp new file mode 100644 index 000000000..ad2d77ee9 --- /dev/null +++ b/bazaar/TestLeptonica/BaseLine.cpp @@ -0,0 +1,56 @@ +#include "TestLeptonica.h" + +static void BaseLine(PixRaster &pixRaster) +{ + CHECKR(pixRaster.DeskewLocal(), "Deskew error"); + Array intArray = pixRaster.FindBaselines(); + CHECKR(intArray.GetCount(), "FindBaselines error"); + PIX *pix = pixRaster; + int width = pixRaster.GetWidth(); + for(int iLine = 0; iLine < intArray.GetCount(); iLine++) + { + int y = intArray[iLine]; + for(int x = 0; x < width; x++) + pixSetPixel(pix, x, y, 1); + } + +} + +void TestLeptonica::onBaseLine() +{ + String fileName; + FileSelector fs; + PIX *pix; + + if(!PromptYesNo( + "[= [* Text baseline analysis demo]&&" + "Please select a scanned, 1 bpp text image&" + "you can take 'keystone.png' from TestLeptonica folder if you like&&" + "[* CONTINUE ??]]" + )) + return; + + fs.ReadOnlyOption(); + if(fs.ExecuteOpen("Please select image for text baseline analysis:")) + { + FileIn s; + if(!s.Open(~fs)) + { + PromptOK("Error opening image"); + s.Close(); + return; + } + + // Loads pixraster from source raster + CHECKR(pixRaster.Load(s), "Error loading image"); + s.Close(); + + // apply line removal algothithm + BaseLine(pixRaster); + + // refresh the PixRasterCtrl control with the new image contents + pixRasterCtrl.Reload(); + pixRasterCtrl.SetPage(0); + + } +} diff --git a/bazaar/TestLeptonica/PageLayout.cpp b/bazaar/TestLeptonica/PageLayout.cpp index fc2895a4f..e7a31be07 100644 --- a/bazaar/TestLeptonica/PageLayout.cpp +++ b/bazaar/TestLeptonica/PageLayout.cpp @@ -13,7 +13,7 @@ void TestLeptonica::onPageLayout() if(!PromptYesNo( "[= [* Page layout analysis demo]&&" - "Please select a scanned image with mixed text and graphics&" + "Please select a 1 bpp scanned image with mixed text and graphics&" "you can take one from TestLeptonica folder if you like&&" "[* CONTINUE ??]]" )) diff --git a/bazaar/TestLeptonica/TestLeptonica.h b/bazaar/TestLeptonica/TestLeptonica.h index f50846858..13757c117 100644 --- a/bazaar/TestLeptonica/TestLeptonica.h +++ b/bazaar/TestLeptonica/TestLeptonica.h @@ -28,6 +28,7 @@ class TestLeptonica : public WithTestLeptonicaLayout // button handlers void onLineRemoval(void); void onPageLayout(void); + void onBaseLine(void); void onQuit(void); // PIX raster diff --git a/bazaar/TestLeptonica/TestLeptonica.lay b/bazaar/TestLeptonica/TestLeptonica.lay index 0811f02b9..02b13e1b5 100644 --- a/bazaar/TestLeptonica/TestLeptonica.lay +++ b/bazaar/TestLeptonica/TestLeptonica.lay @@ -1,7 +1,8 @@ LAYOUT(TestLeptonicaLayout, 640, 400) - ITEM(Button, PageLayoutButton, SetLabel(t_("Page layout test")).LeftPosZ(8, 92).TopPosZ(32, 15)) + ITEM(Button, BaseLineButton, SetLabel(t_("Baseline test")).Tip(t_("Find baseline of text lines of a scanned page")).LeftPosZ(8, 92).TopPosZ(56, 15)) ITEM(Button, QuitButton, SetLabel(t_("\aQuit")).LeftPosZ(8, 92).BottomPosZ(9, 15)) ITEM(PixRasterCtrl, pixRasterCtrl, SetFrame(InsetFrame()).HSizePosZ(108, 8).VSizePosZ(8, 8)) - ITEM(Button, LineRemovalButton, SetLabel(t_("Line removal test")).LeftPosZ(8, 92).TopPosZ(8, 15)) + ITEM(Button, LineRemovalButton, SetLabel(t_("Line removal test")).Tip(t_("Removes horizontal lines from a scanned paper drawing")).LeftPosZ(8, 92).TopPosZ(8, 15)) + ITEM(Button, PageLayoutButton, SetLabel(t_("Page layout test")).Tip(t_("Finds the layout of a page, separating graphics from text")).LeftPosZ(8, 92).TopPosZ(32, 15)) END_LAYOUT diff --git a/bazaar/TestLeptonica/TestLeptonica.upp b/bazaar/TestLeptonica/TestLeptonica.upp index 16b296c75..2768d7129 100644 --- a/bazaar/TestLeptonica/TestLeptonica.upp +++ b/bazaar/TestLeptonica/TestLeptonica.upp @@ -8,6 +8,7 @@ file TestLeptonica.h, LineRemoval.cpp, PageLayout.cpp, + BaseLine.cpp, main.cpp; mainconfig diff --git a/bazaar/TestLeptonica/keystone.png b/bazaar/TestLeptonica/keystone.png new file mode 100644 index 000000000..7b88eb6f5 Binary files /dev/null and b/bazaar/TestLeptonica/keystone.png differ diff --git a/bazaar/TestLeptonica/main.cpp b/bazaar/TestLeptonica/main.cpp index 201eed3f2..ed5505e60 100644 --- a/bazaar/TestLeptonica/main.cpp +++ b/bazaar/TestLeptonica/main.cpp @@ -16,6 +16,7 @@ TestLeptonica::TestLeptonica() // connects button handlers LineRemovalButton <<= THISBACK(onLineRemoval); PageLayoutButton <<= THISBACK(onPageLayout); + BaseLineButton <<= THISBACK(onBaseLine); QuitButton <<= THISBACK(onQuit); }