//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- LeptPrepareFile::LeptPrepareFile(LeptLog &log): Log (log) { bLastProcessingOK = false; angle = 0; conf = 0; SetNULL(4, (void **)&pixRotate000, &pixRotate090, &pixRotate180, &pixRotate270); SetNULL(3, (void **)&pix, &pixClear, &boxFirstCrop); }
void CScValue::SetNative(CBScriptable* Val, bool Persistent) { if(m_Type==VAL_VARIABLE_REF) { m_ValRef->SetNative(Val, Persistent); return; } if(Val==NULL) { SetNULL(); } else { if(m_ValNative && !m_Persistent) { m_ValNative->m_RefCount--; if(m_ValNative->m_RefCount<=0) { if(m_ValNative != Val) delete m_ValNative; m_ValNative = NULL; } } m_Type = VAL_NATIVE; m_Persistent = Persistent; m_ValNative = Val; if(m_ValNative && !m_Persistent) m_ValNative->m_RefCount++; } }
//------------------------------------------------------------------------------ //Ортогональный поворот исходного изображения и обрезка его до //крайней правой нижней части с размером (dX x dY) //------------------------------------------------------------------------------ PIX* LeptPrepareFile::getCroppingRotatePix(PIX *pix, l_int32 degree, l_int32 dX, l_int32 dY) { PIX *pixRotated, *pixCrop; BOX *boxCrop; l_int32 quads; LEP_LOG("enter"); SetNULL(3, (void **)&pixRotated, &pixCrop, &boxCrop); try { LEP_STR_THROW(!pix, "Изображение не найдено"); quads = degree / 90; pixRotated = pixRotateOrth(pix, quads); LEP_STR_THROW(!pixRotated, "Ошибка поворота"); boxCrop = boxCreate(pixRotated->w - dX, pixRotated->h - dY, dX, dY); LEP_STR_THROW(!boxCrop, "Ошибка создания box"); pixCrop = pixClipRectangle(pixRotated, boxCrop, NULL); LEP_STR_THROW(!pixCrop, "Ошибка обрезки"); }catch (string error) { LEP_ERROR(error); }; if (pixRotated) pixDestroy(&pixRotated); if (boxCrop) boxDestroy(&boxCrop); LEP_LOG("exit"); return pixCrop; }
//--------------------------------------------------------------------------- //Поиск основной надписи в указанном файле //findstr - поля для поиска //border - Толщина краёв которая будет очищена в найденных PIX //trustratio - коэф.надёжности //tolerance - предельное отклонение //outTrustRatio - полученное значение с чем сравнивался trustratio //расширеное описание параметров см.boxaGetLinkedBox //--------------------------------------------------------------------------- l_int32 LeptonicaProccesingDrawing::findFrameInFile(string findstr, l_int32 border, l_float32 trustratio, l_int32 tolerance, l_float32 &outTrustRatio) { BOXA *frame; BOX *box; PIX *pixC, *pixR, *pixRbig, *pixTemp; l_int32 result; l_int32 fRes; l_int32 angOtho; l_int32 scale; LEP_LOG("enter"); SetNULL(1, (void**)&frame); result = 1; findFrame.setTolerance(tolerance); findFrame.setTrustRatio(trustratio); try { LEP_STR_THROW(!prepareFile.isLastProcessingOK(), "Файл изображения не инициализирован"); //Разбор строки с описанием полей ParseFieldsStr(findstr, Fields); LEP_STR_THROW(Fields.size() == 0, "Поля не найдены"); //Поиск рамки для каждого изображения pixC = prepareFile.pixRotate000; frame = findFrame.findFrame(pixC, Fields); angOtho = 0; if (!frame) { pixC = prepareFile.pixRotate090; frame = findFrame.findFrame(pixC, Fields); angOtho = 90; } if (!frame) { pixC = prepareFile.pixRotate180; frame = findFrame.findFrame(pixC, Fields); angOtho = 180;} if (!frame) { pixC = prepareFile.pixRotate270; frame = findFrame.findFrame(pixC, Fields); angOtho = 270;} if (frame) { for (int i = 0; i < frame->n; i++) { //пересчёт координат из точки отсчёта обрезанных скоректированных изображений //в точку отсчёта уменьшенного и повернутого изначального изображения //иногда реальная ширина изображения может быть меньше ширины эталона wSmallPix (hSmallPix) //(wSmallPix < pixC->w) ? wSmallPix : pixC->w, удалить //(hSmallPix < pixC->h) ? hSmallPix : pixC->h, удалить box = prepareFile.boxReCalcPosition( frame->box[i], pixC->w, pixC->h, angOtho); if ((prepareFile.pix->xres == 600) && (prepareFile.pix->yres == 600)) scale = 2; else scale = 1; pixTemp = pixGetFromBoxAndAngle(prepareFile.pix, box, -prepareFile.angle, scale); pixRbig = pixRotateOrth(pixTemp, angOtho / 90); boxDestroy(&box); pixDestroy(&pixTemp); pixR = pixClipRectangle(pixC, frame->box[i], NULL); //pixDisplay(pixRbig, 800,800); if (pixRbig) { Fields[i].FieldPIXbig = pixRemoveBorder(pixRbig, border); pixDestroy(&pixRbig); } else LEP_LOG("Ошибка получения поля (big)"); if (pixR) { Fields[i].FieldPIX = pixRemoveBorder(pixR, border); pixDestroy(&pixR); } else LEP_LOG("Ошибка получения поля"); } result = 0; } }catch (string error) { LEP_ERROR(error); }; boxaDestroy(&frame); outTrustRatio = findFrame.getLastOutTrustRatio(); LEP_LOG("exit"); return result; /*PIXA *pixa2 = pixClipRectangles(clearPix, ramka); PIX *pix2 = pixaDisplay(pixa2, 11500, 8600); pix2 = pixMorphSequence(pix2, "d5.5", 0); pixWrite("c:\\pix2.tif", pix2, IFF_TIFF_ZIP); pixDestroy(&pix2); */ //pixDisplay(GetPixFromSTR("Наименование"), 800,800); //pixDisplay(GetPixFromSTR("Обозначение"), 800,800); //pixDisplay(GetPixFromSTR("None4"), 800,800); //pixWrite("c:\\2.tif", pix, IFF_TIFF_ZIP); }
//--------------------------------------------------------------------------- //выстраивает все изображения по вертикали и записывает в файл //filename - имя файла для записи //fields - поля, которые необходимо совместить (через запятую0 //width - ширина до которой идёт ресайз изображения //height - высота до которой идёт ресайз изображения // примечание - задание width height меняет пропорцию изображения // если width = 0, height != 0 , то идёт пропорциональный ресайз всего изображения до height // если height = 0, width != 0 , то идёт пропорциональный ресайз всего изображения до width //proportion - флаг пропорционального ресайза изображения согласно заданным width и height // примечение // proportion!=0 пропорциональный ресайз // если компонент width=0 или height=0 то он игнорируется // width, height - устанавливают максимальное(!) значение // proportion=0 НЕпропорциональный ресайз // действует только при height!=0 и width!=0 //proportion - =0 если необходимо НЕпропорциональное уменьшение согласно заданным width и height //ImageFormat - файловый формат ("tiffG4", "tiffZIP", "png", "bmp", "jpg") //--------------------------------------------------------------------------- l_int32 LeptonicaProccesingDrawing::debugOutputImage(string filename, string fields, l_int32 width, l_int32 height, l_int32 proportion, string ImageFormat) { /*pixWriteMemBmp pixWriteStreamBmp pixWriteTiff pixWriteStreamTiff pixFillMapHoles */ PIX *pix, *pixM, *pixR; PIXA *pixa; l_int32 result; l_int32 format; l_int32 w, h; double dW, dH; LEP_LOG("enter"); SetNULL(3, (void**)&pix, &pixM, &pixa); try { pixa = pixaCreate(3); LEP_STR_THROW(!pixa, "Ошибка создания pixa"); vector<string> VN = split(fields, ','); for (unsigned int n = 0; n < VN.size(); n++) { pix = GetPixFromSTR(VN[n]); if (pix) pixaAddPix(pixa, pix, L_COPY); } pixM = pixaDisplayLinearly(pixa, L_VERT, 1, 0, 10, 8, NULL); LEP_STR_THROW(!pixM, "Ошибка создания совмещения pixa"); if ((proportion == 0) || (width == 0) || (height == 0) ) { pixR = pixScaleToSize(pixM, width, height); LEP_STR_THROW(!pixR, "Ошибка изменения размера"); } else { w = 0; h = 0; dW = pixM->w / (double)width; dH = pixM->h / (double)height; if (dW > dH) w = width; else h = height; pixR = pixScaleToSize(pixM, w, h); LEP_STR_THROW(!pixR, "Ошибка изменения размера"); } if (ImageFormat == "tiffG4") format = IFF_TIFF_G4; if (ImageFormat == "tiffZIP") format = IFF_TIFF_ZIP; if (ImageFormat == "png") format = IFF_PNG; if (ImageFormat == "bmp") format = IFF_BMP; if (ImageFormat == "jpg") format = IFF_JFIF_JPEG; result = pixWrite(filename.c_str(), pixR, format); LEP_STR_THROW(result != 0, "Ошибка создания совмещения pixa"); }catch (string error) { LEP_ERROR(error); }; pixDestroy(&pixM); pixaDestroy(&pixa); LEP_LOG("exit"); return 0; }
bool CScValue::DbgSetVal() { SetNULL(); return true; }
//--------------------------------------------------------------------------- //Уменьшение в 2 раза //Поиск угла //Предварительное выпрямление //Эрозия для удаления тонких линий //Поиск box для обрезки белых полей изображения //Обрезка предварительно выпрямленного изображения //Получение трёх изображений: //------------------------------------------------------------------------------ PIX* LeptPrepareFile::getClearImage(PIX *pix, l_float32 *angle, l_float32 *conf) { PIX *pixReduce2, *pixDeskew, *pixCrop, *pixErode; PIXA *pixa1, *pixa2; l_int32 result; l_float32 _angle, _conf; l_int32 XC_crop, YC_crop, XC_old, YC_old, XC_new, YC_new; LEP_LOG("enter"); SetNULL(7, (void **)&pixReduce2, &pixDeskew, &pixCrop, &pixErode, &pixa1, &pixa2, &boxFirstCrop); SetNULL(2, (void **)angle, conf); try { LEP_STR_THROW(!pix, "Изображение не найдено"); //Уменьшение в 2 раза для ускорения (при DPI = 600) if ((pix->xres == 600) && (pix->yres == 600)) //В дальнейшем переработать потому как в текущем варианте обрабатывает корректно только DPI300 и DPI600 pixReduce2 = pixReduceBinary2(pix, NULL); else { pixReduce2 = pixCreateTemplateNoInit(pix); LEP_STR_THROW(!pixReduce2, "Ошибка в pixReduceBinary2"); pixCopy(pixReduce2, pix); } LEP_STR_THROW(!pixReduce2, "Ошибка в pixReduceBinary2"); //Поиск угла наклона result = pixFindSkewSweepAndSearch(pixReduce2, &_angle, &_conf, 4, //линеное уменьшение, DEFAULT_SWEEP_REDUCTION = 4 2, //бинарное уменьшение, DEFAULT_BS_REDUCTION = 2 10, //максимальный угол поиска 0.1, //дельта угла поиска 0.01);//конечная дельта угла поиска, DEFAULT_MINBS_DELTA = 0.01 LEP_STR_THROW(result != 0, "Ошибка поиска угла"); if (angle) *angle = _angle; if (conf) *conf = _conf; //Предварительное выпрямление pixDeskew = pixRotate(pixReduce2, 3.1415926535 / 180. * _angle, L_ROTATE_AREA_MAP, L_BRING_IN_WHITE, 0, 0); LEP_STR_THROW(!pixDeskew, "Ошибка при предварительном повороте изображения"); //Эрозия для удаления тонких линий pixErode = pixCreateTemplateNoInit(pixDeskew); LEP_STR_THROW(!pixErode, "Ошибка в pixCreateTemplateNoInit"); pixCopy(pixErode, pixDeskew); pixErodeBrick(pixErode, pixErode, 3, 3); //pixWrite("c:\\temp0_0.tif", pixErode, IFF_TIFF_ZIP); //Поиск box для обрезки белых полей изображения result = pixClipBoxToForeground(pixErode, NULL, NULL, &boxFirstCrop); LEP_STR_THROW(result != 0, "Ошибка при поиске обрезки изображения"); //Получение точки вокруг которой происходило вращение, с учётом обрезки XC_old = pixErode->w / 2; //точка вращения старого изображения на старом изображении YC_old = pixErode->h / 2; XC_new = boxFirstCrop->w / 2; //точка вращения нового изображения на новом изображении YC_new = boxFirstCrop->h / 2; XC_crop = boxFirstCrop->x + XC_new; //точка вращения нового изображения на старом изображении YC_crop = boxFirstCrop->y + YC_new; centerXRotate = XC_new - (XC_crop - XC_old); //точка вращения старого изображения на новом изображении centerYRotate = YC_new - (YC_crop - YC_old); //Обрезка предварительно выпрямленного изображения pixCrop = pixClipRectangle(pixDeskew, boxFirstCrop, NULL); LEP_STR_THROW(!pixCrop, "Ошибка при обрезке изображения"); //pixWrite("c:\\pixCrop.tif", pixCrop, IFF_TIFF_ZIP); }catch (string error) { LEP_ERROR(error); }; pixDestroy(&pixReduce2); pixDestroy(&pixDeskew); pixDestroy(&pixErode); LEP_LOG("exit"); return pixCrop; }