void PDFwin::pageChanged() { int ww=w()-2; int hh=h()-2; if(!mModel) return; if(!mModel->cacheValid(ww, hh, mCurrPage)) { mState="load"; redraw(); Fl::check(); mState="none"; } CImage* bmp_orig=mModel->getPage(ww, hh, mCurrPage); if(mLayout->findCheckButton("Use automatic segmentation")->value()) { CImage temp; temp.CopyFrom(*bmp_orig); #ifdef DEBUG_FONT_DETECTION CImage* bmp=bmp_orig; #else CImage* bmp=&temp; #endif { intmatrixn& textCache=*mModel->_textCache[mCurrPage]; #ifdef USE_FONT_DETECTION const bool drawLetterBoundingBox=true; const bool drawDetectedSpace=true; #else const bool drawLetterBoundingBox=false; const bool drawDetectedSpace=false; #endif if(drawLetterBoundingBox) { CImagePixel ip(bmp); for(int i=0; i<textCache.rows()-1; i++) { int* info=textCache[i]; int c=info[TC_c]; int x=info[TC_x]; int y=info[TC_y]; int w=info[TC_w]; int h=info[TC_h]; int fx=info[TC_fx]; int fy=info[TC_fy]; if (std::abs(y-textCache[i+1][TC_y])<=3) // draw excluding trailing space { #ifdef DEBUG_FONT_DETECTION ip.DrawLineBox(TRect(x-fx,y-fy, x-fx+w, y-fy+h), CPixelRGB8(0,0,0)); #else ip.DrawBox(TRect(x-fx,y-fy, x-fx+w, y-fy+h), CPixelRGB8(0,0,0)); #endif ip.DrawHorizLine(x, y, w, CPixelRGB8(255,0,0)); } // else printf("%d %d %d %d\n", x,y, textCache[i+1][TC_x], textCache[i+1][TC_y]); } } FlLayout* layout=mLayout->findLayout("Automatic segmentation"); double min_text_gap=layout->findSlider("MIN text-gap")->value(); if(drawDetectedSpace) { CImagePixel ip(bmp); for(int i=1; i<textCache.rows(); i++) { int* pinfo=textCache[i-1]; int* info=textCache[i]; if(pinfo[TC_y]==info[TC_y]) { int prevEnd=pinfo[TC_x]-pinfo[TC_fx]+pinfo[TC_w]-1; int curStart=info[TC_x]-info[TC_fx]; int bottom=MIN(pinfo[TC_y]-pinfo[TC_fy], info[TC_y]-info[TC_fy]); int top=MAX(pinfo[TC_y]-pinfo[TC_fy]+pinfo[TC_h], info[TC_y]-info[TC_fy]+info[TC_h]); int space_thr=MAX(pinfo[TC_h], pinfo[TC_w]); space_thr=MAX(space_thr, info[TC_h]); space_thr=MAX(space_thr, info[TC_w]); space_thr*=min_text_gap; if(curStart-prevEnd<=space_thr && curStart>prevEnd) { // mark as space. ip.DrawBox(TRect(prevEnd, bottom, curStart, top), CPixelRGB8(0,0,0)); } } } } } SummedAreaTable t(*bmp);//bmp->getWidth(), bmp->getHeight(), bmp->getDataPtr(), bmp->getRowSize()); FlLayout* layout=mLayout->findLayout("Automatic segmentation"); double min_gap_percentage=layout->findSlider("MIN gap")->value(); double margin_percentage=layout->findSlider("Margin")->value(); int thr_white=layout->findSlider("white point")->value(); double max_width=1.0/layout->findSlider("N columns")->value(); double cropT=layout->findSlider("Crop T")->value()/100.0; double cropB=layout->findSlider("Crop B")->value()/100.0; double cropL=layout->findSlider("Crop L")->value()/100.0; double cropR=layout->findSlider("Crop R")->value()/100.0; // TRect domain(0,0, bmp->GetWidth(), bmp->GetHeight()); TRect domain(cropL*bmp->GetWidth(),cropT*bmp->GetHeight(), (1-cropR)*bmp->GetWidth() , (1-cropB)*bmp->GetHeight()); ImageSegmentation s(t, true, domain, 0, min_gap_percentage, thr_white); s.segment(); std::list<TRect> results; s.getResult(results, max_width, margin_percentage); /* std::list<TRect> results; int min_gap=int((double)bmp->GetWidth()*min_gap_percentage*0.01 +0.5); int min_box_size=100; // 10�ȼ������� �ڽ��� ������. CImagePixel orig(bmp_orig); std::list<index2> LRcorners; std::list<index2> ULcorners; for(int i=0, ni=bmp->GetWidth()-min_box_size-min_gap; i<ni; i++) { for(int j=0, nj=bmp->GetHeight()-min_box_size-min_gap; j<nj; j++) { // search for LR corner TRect outerBox(i, j, i+min_box_size+min_gap, j+min_box_size+min_gap); TRect innerBox(i, j, i+min_box_size, j+min_box_size); int sum1=t.sum(outerBox); int sum2=t.sum(innerBox); int area=outerBox.Width()*outerBox.Height()- innerBox.Width()*innerBox.Height(); if(sum1-sum2 >= thr_white*area) { //orig.SetPixel(i+min_box_size+min_gap/2,j+min_box_size+min_gap/2,CPixelRGB8(255,0,0)); LRcorners.push_back(index2(i+min_box_size+min_gap/2,j+min_box_size+min_gap/2)); } // search for UL corner { TRect outerBox(i, j, i+min_box_size+min_gap, j+min_box_size+min_gap); TRect innerBox(i+min_gap, j+min_gap, i+min_box_size+min_gap, j+min_box_size+min_gap); int sum1=t.sum(outerBox); int sum2=t.sum(innerBox); int area=outerBox.Width()*outerBox.Height()- innerBox.Width()*innerBox.Height(); if(sum1-sum2 >= thr_white*area) { // orig.SetPixel(i+min_gap/2,j+min_gap/2,CPixelRGB8(0,0,255)); ULcorners.push_back(index2(i+min_gap/2,j+min_gap/2)); } } } } { std::list<index2>::iterator i; for(i=ULcorners.begin(); i!=ULcorners.end(); ++i) { orig.SetPixel((*i).x(), (*i).y(), CPixelRGB8(0,0,255)); } } */ mRects.clear(); int x=toWindowCoord(0,0).x; int y=toWindowCoord(0,0).y; std::list<TRect>::iterator i; for(i=results.begin(); i!=results.end(); i++) { mRects.push_back(SelectionRectangle()); mSelectedRect=mRects.end(); mSelectedRect--; SelectionRectangle& mRect=selectedRect(); mRect.p1=toDocCoord((*i).left+x, (*i).top+y); mRect.p2=toDocCoord((*i).right+x, (*i).bottom+y); mRect.updateScreenCoord(*this); } } }