Podofo PDF table and AutoPageBreak - c++

Can somebody help me to get working the AutoPageBreak function of Podofo::PdfTable class?
I write so
table1.SetAutoPageBreak(true,
[](PoDoFo::PdfRect &rect, void* pCustom)->PoDoFo::PdfPage*{
PoDoFo::PdfPage *pPage = new PoDoFo::PdfPage(rect,(PoDoFo::PdfStreamedDocument*)pCustom);
rect = PoDoFo::PdfRect(0,0,pPage->GetPageSize().GetWidth(), pPage->GetPageSize().GetHeight());
cout << "qui" << endl;
return pPage;
}, (void*) document);
the function is called correctly but does nothing, the first page is correctly created but the new page is not created.
http://podofo.sourceforge.net/doc/html/classPoDoFo_1_1PdfTable.html#ac33e4bf489d3b7232deae271b8dc552a
the rest of source code is here
document = new PoDoFo::PdfStreamedDocument("doc.pdf");
PoDoFo::PdfPainter painter;
PoDoFo::PdfTable table1 = PoDoFo::PdfTable(2, length);
table1.SetAutoPageBreak(true,
[](PoDoFo::PdfRect &rect, void* pCustom)->PoDoFo::PdfPage*{
PoDoFo::PdfPage *pPage = new PoDoFo::PdfPage(rect,(PoDoFo::PdfStreamedDocument*)pCustom);
rect = PoDoFo::PdfRect(0,0,pPage->GetPageSize().GetWidth(), pPage->GetPageSize().GetHeight());
cout << "qui" << endl;
return pPage;
}, (void*) document);
PoDoFo::PdfSimpleTableModel* tablemodel1 = new PoDoFo::PdfSimpleTableModel(2, length);
PoDoFo::PdfPage* pPage = document->CreatePage(PoDoFo::PdfPage::CreateStandardPageSize(PoDoFo::ePdfPageSize_A4, true));
painter.SetPage(pPage);
PoDoFo::PdfFont* pFont = document->CreateFontSubset("NotoSansMono", false, false, false, PoDoFo::PdfEncodingFactory::GlobalStandardEncodingInstance(), "NotoSansMono-VariableFont_wdth,wght.ttf");
//PoDoFo::PdfFont* pFont = document.CreateFont("Courier");
pFont->SetFontSize(8);
painter.SetFont(pFont);
tablemodel1->SetFont(pFont);
tablemodel1->SetForegroundColor(PoDoFo::PdfColor(0.0, 0.0, 0.0));
tablemodel1->SetBorderEnabled(true);
tablemodel1->SetBorderWidth(0.5);
tablemodel1->SetAlignment(PoDoFo::EPdfVerticalAlignment::ePdfVerticalAlignment_Top);
tablemodel1->SetWordWrapEnabled(true);
painter.DrawTextAligned(20, pPage->GetPageSize().GetHeight()-20, pPage->GetPageSize().GetWidth(), "Riassunto giornaliero risorse", PoDoFo::EPdfAlignment::ePdfAlignment_Center);
string text = "";
vector<OggettoEventoItem*>* listaOggettiEventi;
vector<EventoItem*>* eventoItem;
double rowheight[(int)oggettiSel->size()];
double totrowheight = 0;
for (int i = 0; i < (int)oggettiSel->size(); i++)
{
tablemodel1->SetText(0, i, oggettiSel->at(i)->GetLabel().ToStdString());
for(int j = 0; j < (int)listaOggettiEventi->size(); j++)
{
text += "...";
}
tablemodel1->SetText(1, i, text);
char newline = '\n';
int count = std::count(text.begin(), text.end(), newline);
if(count > 0)
rowheight[i] = count * 20;
else
rowheight[i] = 20;
totrowheight += rowheight[i];
text = "";
}
table1.SetModel(tablemodel1);
double colwidth[2] = { 150, pPage->GetPageSize().GetWidth() - 150 - 40};
table1.SetColumnWidths(colwidth);
table1.SetRowHeights(rowheight);
table1.SetTableWidth(pPage->GetPageSize().GetWidth()-40);
table1.SetTableHeight(pPage->GetPageSize().GetHeight()-60);
table1.Draw(20, pPage->GetPageSize().GetHeight()- 40, &painter);
painter.FinishPage();
document->Close();
Sorry for my bad english and thanks a lot in advance

table1.SetAutoPageBreak(true,
[](PoDoFo::PdfRect &rect, void* pCustom)->PoDoFo::PdfPage*{
PoDoFo::PdfPage *pPage = ((PoDoFo::PdfStreamedDocument*)pCustom)->CreatePage(PoDoFo::PdfPage::CreateStandardPageSize(PoDoFo::ePdfPageSize_A4, true));
return pPage;
}, (void*) document);
I solved, was more easy than expected.

Related

Image::GetFrameCount sets Image::LastError to win32error c++ gdi+

This function changes active frame of image after some time
But when i try to get frame count of the dimension it sets image->lasterror to Win32Error
Is there is any way to fix it?
(Windows 10,Visual Studio 2017 community)
void PlayImageAnim(Gdiplus::Image*&image, int delay,bool Looped)
{
using namespace Gdiplus;
if (Looped == true)
{
while (true)
{
UINT dcount = 0;
GUID *dimensionsIDs;
dcount = image->GetFrameDimensionsCount();
dimensionsIDs = new GUID[dcount];
UINT frame_count = image->GetFrameCount(&dimensionsIDs[0]);
int y = 0;
GUID pageGUID = FrameDimensionTime;
int size = image->GetPropertyItemSize(PropertyTagFrameDelay);
Gdiplus::PropertyItem*pr_item = (Gdiplus::PropertyItem*)malloc(size);
for (UINT i = 0; i <= frame_count; i++)
{
/*graphics.DrawImage(image, image_rect);*/
/*long delay = ((long*)pr_item->value)[i] * 10;*/
image->SelectActiveFrame(&pageGUID, i);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
image->SelectActiveFrame(&pageGUID, 0);
}
}
else
{
UINT dcount = 0;
GUID *dimensionsIDs;
dcount = image->GetFrameDimensionsCount();
dimensionsIDs = new GUID[dcount];
UINT frame_count = image->GetFrameCount(&dimensionsIDs[0]);
GUID pageGUID = FrameDimensionTime;
int size = image->GetPropertyItemSize(PropertyTagFrameDelay);
Gdiplus::PropertyItem*pr_item = (Gdiplus::PropertyItem*)malloc(size);
for (UINT i = 0; i <= frame_count; i++)
{
image->SelectActiveFrame(&pageGUID, i);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
image->SelectActiveFrame(&pageGUID, 0);
}
}
it has to similar parts for other parts of project

SDL text box highlighting text

I am making a program in C++ that uses SDL to display text boxes. I've made the basic functions of my text boxes like typing text, limitations, copy/paste, etc. but I am stuck at make it able to highlight text.
Here's how I draw textboxes:
void draw_text_box(SDL_Surface *screan, char *message, struct textbox *text_box, int r, int g, int b)
{
int temp_width;
int temp_frame;
SDL_Surface *text;
SDL_Color textcolor = {0,0,0,0};
SDL_Rect temp_location, clr_box;
temp_width = text_box->location.w; //preserve the correct width
temp_location = text_box->location;
temp_location.y += 4;
temp_location.h = 12;
clr_box = text_box->location;
//colors!
textcolor.r = r;
textcolor.g = g;
textcolor.b = b;
//text = TTF_RenderText_Solid(ttf_font, text_box->prev_message, textcolor);
//SDL_BlitSurface( text, NULL, screan, &text_box->location);//<-changes "location" width to width of text
//clear
SDL_FillRect(screan, &clr_box, SDL_MapRGB(screen->format, 0, 0, 0));
//strcpy(text_box->prev_message, message);
//set the text
text = TTF_RenderText_Solid(ttf_font, message, textcolor);
if(!text) return;
//set the offset
temp_location.x = text_box->last_shift;
temp_location.y = 0;
temp_location.h = text->h;
if(text_box->cursor_loc - text_box->last_shift > temp_location.w)
temp_location.x = text_box->cursor_loc - temp_location.w;
if(text_box->cursor_loc - 3 < text_box->last_shift)
temp_location.x = text_box->cursor_loc - 3;
if(temp_location.x < 0) temp_location.x = 0;
text_box->last_shift = temp_location.x;
//draw
SDL_BlitSurface( text, &temp_location, screan, &text_box->location);//<-changes "location" width to width of text
text_box->location.w = temp_width;
}
Setting the text:
void set_text_box_text(SDL_Surface *screan, struct textbox *text_box, char *message)
{
if(text_box->message != message)
strcpy(text_box->message, message);
text_box->char_amt = strlen(message);
text_box->cursor = text_box->char_amt;
text_box->last_shift = 0;
if (screan) //if not NULL
{
if (text_box->selected)
select_text_box(screan,text_box);
else
unselect_text_box(screan,text_box);
}
else
{
;//text_box->prev_message[0] = '\0';
}
}
Select and deselect the textbox:
void select_text_box(SDL_Surface *screan, struct textbox *text_box)
{
char temp_message[405] = "";
char temp_left[405];
int i;
text_box->selected = 1;
if (text_box->pass_char == '\0')
{
if (text_box->cursor != 0)
{
left(temp_left, text_box->message, text_box->cursor);
strcat(temp_message, temp_left);
}
temp_message[text_box->cursor] = '|';
temp_message[text_box->cursor + 1] = '\0';
right(temp_left, text_box->message, text_box->cursor);
strcat(temp_message, temp_left);
}
else
{
for(i=0;i<text_box->cursor;i++)
temp_message[i] = text_box->pass_char;
temp_message[i] = '|';
for(i++;i<text_box->char_amt + 1;i++)
temp_message[i] = text_box->pass_char;
temp_message[i] = '\0';
}
draw_text_box(screan, temp_message, text_box, 250, 250, 250);
}
void unselect_text_box(SDL_Surface *screan, struct textbox *text_box)
{
char temp_message[405];
int i;
text_box->selected = 0;
if (text_box->pass_char == '\0')
draw_text_box(screan, text_box->message, text_box, 250, 250, 250);
else
{
for(i=0;i<text_box->char_amt;i++)
temp_message[i] = text_box->pass_char;
temp_message[i] = '\0';
draw_text_box(screan, temp_message, text_box, 250, 250, 250);
}
}

Extract text location by hooking ExtTextOutW

I have question regarding the Windows APIs RedrawWindow , ExtTextOut and BitBlt .
I am hooking the ExtTextOut to extract the text location on screen, if I call RedrawWindow with parameter lprcUpdate = NULL and hrgnUpdate = NULL:
WindowWrapper.RedrawWindow(topWnd, IntPtr.Zero, IntPtr.Zero, RedrawWindowFlags.UpdateNow | RedrawWindowFlags.Frame | RedrawWindowFlags.Invalidate | RedrawWindowFlags.AllChildren | RedrawWindowFlags.Erase);
In hooked function ExtTextOut, I call LPToDP API to translate the location to device context location. Then it works fine. The text location is correct.
WindowWrapper.LPtoDP(hdc, arrPoint, 2);
But, if I call
WindowWrapper.RedrawWindow(topWnd, ref location, IntPtr.Zero, RedrawWindowFlags.UpdateNow | RedrawWindowFlags.Frame | RedrawWindowFlags.Invalidate | RedrawWindowFlags.AllChildren | RedrawWindowFlags.Erase);
Then it fails. The location is incorrect. I see that it translated by using LPToDP into incorrect location.
Any one know about this problem? How can we fix it?
public static bool ExtTextOutW_Hook(IntPtr hdc, int X, int Y, uint fuOptions,
IntPtr lprc, [MarshalAs(UnmanagedType.LPWStr)] string lpString,
uint cbCount, IntPtr lpDx)
{
try
{
lock (IsRetrievingSynch)
{
if (IsRetrieving && !string.IsNullOrEmpty(lpString) && cbCount > 0)
{
TextData textData = new TextData();
textData.FuncName = "ExtTextOutW";
char[] text = new char[cbCount];
bool isGlyphIndex = ((fuOptions & 0x0010) == 0x0010);
//ETO_GLYPH_INDEX
if (isGlyphIndex)
{
FontMap fontMap = GlyphCharMap.LoadGlyphCharMap(hdc);
if (fontMap != null && fontMap.GlyphCharMap != null)
{
for (int i = 0; i < cbCount; i++)
{
ushort glyph = lpString[i];
if (glyph < fontMap.GlyphCharMap.Length)
{
if (fontMap.GlyphCharMap[glyph] != 0)
{
text[i] = (char)(fontMap.GlyphCharMap[glyph]);
}
else
{
text[i] = (char)32;
}
}
else
{
text[i] = (char)glyph;
}
}
}
}
else
{
for (int i = 0; i < cbCount; i++)
{
text[i] = lpString[i];
}
}
textData.Text = new string(text);
textData.Text = textData.Text.Normalize(NormalizationForm.FormKC);
//textData.Text = textData.Text.Trim();
if (!string.IsNullOrEmpty(textData.Text))
{
int realCount = textData.Text.Length;
TEXTMETRICW tm = new TEXTMETRICW();
WindowWrapper.GetTextMetricsW(hdc, out tm);
int[] nWidth = new int[1];
WindowWrapper.GetCharWidth32W(hdc, ' ', ' ', nWidth);
textData.CharHeight = tm.tmHeight;
textData.CharWidth = nWidth[0];
textData.CharWidths = new int[realCount];
for (int i = 0; i < realCount; i++)
{
nWidth = new int[1];
WindowWrapper.GetCharWidth32W(hdc, textData.Text[i], textData.Text[i], nWidth);
textData.CharWidths[i] = nWidth[0];
}
uint textAlign = WindowWrapper.GetTextAlign(hdc);
POINT ptStartPos = new POINT();
if ((textAlign & WindowWrapper.TA_UPDATECP) > 0)
{
WindowWrapper.GetCurrentPositionEx(hdc, out ptStartPos);
}
else
{
ptStartPos.X = X;
ptStartPos.Y = Y;
}
switch (textAlign & (WindowWrapper.TA_BASELINE | WindowWrapper.TA_BOTTOM | WindowWrapper.TA_TOP))
{
case WindowWrapper.TA_BOTTOM:
textData.Location.Top = Y - tm.tmHeight;
textData.Location.Bottom = Y;
break;
case WindowWrapper.TA_BASELINE:
textData.Location.Top = Y - tm.tmAscent;
textData.Location.Bottom = Y + tm.tmDescent;
break;
case WindowWrapper.TA_TOP:
default:
textData.Location.Top = Y;
textData.Location.Bottom = Y + tm.tmHeight;
break;
}
int nLAlign = 0, nRAlign = 0;
switch (textAlign & (WindowWrapper.TA_LEFT | WindowWrapper.TA_RIGHT | WindowWrapper.TA_CENTER))
{
case WindowWrapper.TA_LEFT:
nLAlign = 0;
nRAlign = 2;
break;
case WindowWrapper.TA_CENTER:
nLAlign = -1;
nRAlign = 1;
break;
case WindowWrapper.TA_RIGHT:
nLAlign = -2;
nRAlign = 0;
break;
}
SIZE size = new SIZE();
if (WindowWrapper.GetTextExtentPoint32W(hdc, lpString, (int)cbCount, ref size))
{
textData.Location.Left = X + nLAlign * (size.CX / 2);
textData.Location.Right = X + nRAlign * (size.CX / 2);
}
else
{
textData.Location.Left = X - 20;
textData.Location.Right = X + 20;
}
LogFactory.RemoteLog.TraceDebug(string.Format("1.ExtTextOutW {0} {1} {2} {3} {4}",
textData.Text, textData.Location.Left, textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top));
//Utility.ClipViewPort(hdc, ref textData.Location);
POINT[] arrPoint = new POINT[2];
arrPoint[0] = new POINT()
{
X = textData.Location.Left,
Y = textData.Location.Top
};
arrPoint[1] = new POINT()
{
X = textData.Location.Right,
Y = textData.Location.Bottom
};
POINT ptDCOrg = new POINT();
WindowWrapper.LPtoDP(hdc, arrPoint, 2);
textData.Location.Left = arrPoint[0].X;
textData.Location.Top = arrPoint[0].Y;
textData.Location.Right = arrPoint[1].X;
textData.Location.Bottom = arrPoint[1].Y;
WindowWrapper.GetDCOrgEx(hdc, out ptDCOrg);
textData.Location.Left += ptDCOrg.X;
textData.Location.Top += ptDCOrg.Y;
textData.Location.Right += ptDCOrg.X;
textData.Location.Bottom += ptDCOrg.Y;
LogFactory.RemoteLog.TraceDebug(string.Format("2.ExtTextOutW {0} {1} {2} {3} {4}",
textData.Text, textData.Location.Left, textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top));
StringBuilder fontName = new StringBuilder();
fontName.Capacity = 260;
WindowWrapper.GetTextFace(hdc, 260, fontName);
textData.Font = fontName.ToString();
IntPtr hWnd = WindowWrapper.WindowFromDC(hdc);
if (WindowWrapper.IsWindowVisible(hWnd))
{
textData.Hdc = hdc;
textData.Hwnd = hWnd;
textData.ZOrder = WindowWrapper.GetZOrder(hWnd);
if (Utility.IsIntersect(_location, textData.Location) && WindowWrapper.IsChildWindow(_topWindow, hWnd))
{
LogFactory.RemoteLog.TraceVerbose(string.Format("3.ExtTextOutW {0} {1} {2} {3} {4} Z-Order: {5}",
textData.Text,
textData.Location.Left,
textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top,
textData.ZOrder));
if (TextDataChannel != null)
TextDataChannel.SendTextData(textData);
}
}
else
{
textData.Hdc = hdc;
//if (lpDx != IntPtr.Zero)
// Utility.ClipViewPort(hdc, ref textData.Location);
_tempDataList.Add(textData);
}
}
}
}
}
catch (Exception ex)
{
LogFactory.RemoteLog.TraceError("ExtTextOutW " + ex.Message);
}
return ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
}
Thanks.

Getting error code C2228: left of '._Ptr' must have class/struct/union

I am getting this strange error code when I try to execute this line of code.
cType += file_size(is_directory( d->status()));
Here is part of the code leading up to the error.
void scan(string switches, path const& f, unsigned k = 0)
{
// Declare file types
long long cppType = 0, cType = 0,
hType = 0, hppType = 0,
hxxType = 0, javaType = 0,
totalClassType = 0, aviType = 0,
mkvType = 0, mpegType = 0,
mp4Type = 0, mp3Type = 0;
int cpp = 0, c = 0, h = 0, hpp = 0, hxx = 0, java = 0,
totalClass = 0, avi = 0, mkv = 0, mpeg = 0, mp4 = 0, mp3 = 0;
int totalBytes = 0;
string indent(k, '\t');
directory_iterator temp;
directory_iterator d(f); //f = the first file in folder to be processed
directory_iterator e; // signals end of folder
bool isReverse = false;
bool isRecursive = false;
path pth;
pth = d->path();
for (unsigned check = 0; check < switches.size(); ++check)
{
if (switches[check] == 'r')
{
isRecursive = true;
}
else if (switches[check] == 'R')
{
isReverse = true;
}
}
for (unsigned int i = 0; i < switches.size(); ++i)
{
if (switches[i] == 'c')
//OPTION c: Locate c++ files - extension(s): .c,. cpp, .h, .hpp, .hxx
{
if (pth.extension() == ".c")
{
c++;
cType += file_size(is_directory(d->status()));
}
Any help is very much appreciated!
is_directory() returns a bool, not a Path, which is what file_size() takes as an argument.
The error you get probably means that file_size() is a macro, which means that this:
file_size(is_directory( d->status()))
is being expanded at some point to:
is_directory( d->status())._Ptr
which can't work, since the . operator can't be applied to bool values.

Some new version of opencv_performance for opencv_traincascade?

I have noted that the cascades trained with the program opencv_traincascade does not run with the current version of opencv_performance. I've tried to convert the old performance cpp file to load the new types of cascades, but without success. The code is here:
#include "cv.h"
#include "highgui.h"
#include <cstdio>
#include <cmath>
#include <ctime>
#include <math.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX 512
#endif /* PATH_MAX */
/*typedef struct HidCascade {
int size;
int count;
} HidCascade;
*/
typedef struct ObjectPos {
float x;
float y;
float width;
int found; /* for reference */
int neghbors;
} ObjectPos;
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
int i, j;
char* classifierdir = NULL;
//char* samplesdir = NULL;
int saveDetected = 1;
double scale_factor = 1.1;
float maxSizeDiff = 1.5F;
float maxPosDiff = 1.1F;
/* number of stages. if <=0 all stages are used */
//int nos = -1, nos0;
int width = 25;
int height = 15;
int rocsize;
FILE* info;
FILE* resultados;
char* infoname;
char fullname[PATH_MAX];
//char detfilename[PATH_MAX];
char* filename;
//char detname[] = "det-";
CascadeClassifier cascade;
double totaltime;
if (!(resultados = fopen("resultados.txt", "w"))) {
printf("Cannot create results file.\n");
exit(-1);
}
infoname = (char*) "";
rocsize = 20;
if (argc == 1) {
printf("Usage: %s\n -data <classifier_directory_name>\n"
" -info <collection_file_name>\n"
" [-maxSizeDiff <max_size_difference = %f>]\n"
" [-maxPosDiff <max_position_difference = %f>]\n"
" [-sf <scale_factor = %f>]\n"
" [-ni]\n"
" [-rs <roc_size = %d>]\n"
" [-w <sample_width = %d>]\n"
" [-h <sample_height = %d>]\n", argv[0], maxSizeDiff,
maxPosDiff, scale_factor, rocsize, width, height);
return 0;
}
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-data")) {
classifierdir = argv[++i];
} else if (!strcmp(argv[i], "-info")) {
infoname = argv[++i];
} else if (!strcmp(argv[i], "-maxSizeDiff")) {
maxSizeDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-maxPosDiff")) {
maxPosDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-sf")) {
scale_factor = atof(argv[++i]);
} else if (!strcmp(argv[i], "-ni")) {
saveDetected = 0;
} else if (!strcmp(argv[i], "-rs")) {
rocsize = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-w")) {
width = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-h")) {
height = atoi(argv[++i]);
}
}
if (!cascade.load(classifierdir)) {
printf("Unable to load classifier from %s\n", classifierdir);
return 1;
}
strcpy(fullname, infoname);
filename = strrchr(fullname, '\\');
if (filename == NULL) {
filename = strrchr(fullname, '/');
}
if (filename == NULL) {
filename = fullname;
} else {
filename++;
}
info = fopen(infoname, "r");
totaltime = 0.0;
if (info != NULL) {
int x, y, width, height;
Mat img;
int hits, missed, falseAlarms;
int totalHits, totalMissed, totalFalseAlarms;
int found;
float distance;
int refcount;
ObjectPos* ref;
int detcount;
ObjectPos* det;
int error = 0;
int* pos;
int* neg;
pos = (int*) cvAlloc(rocsize * sizeof(*pos));
neg = (int*) cvAlloc(rocsize * sizeof(*neg));
for (i = 0; i < rocsize; i++) {
pos[i] = neg[i] = 0;
}
printf("+================================+======+======+======+\n");
printf("| File Name | Hits |Missed| False|\n");
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
fprintf(resultados,
"| File Name | Hits |Missed| False|\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//fprintf (resultados, "%d\n",framesCnt);
totalHits = totalMissed = totalFalseAlarms = 0;
while (!feof(info)) {
fscanf(info, "%s %d", filename, &refcount);
img = imread(fullname);
if (!img.data) {
cout << "ow" << endl;
return -1;
}
ref = (ObjectPos*) cvAlloc(refcount * sizeof(*ref));
for (i = 0; i < refcount; i++) {
error = (fscanf(info, "%d %d %d %d", &x, &y, &width, &height)
!= 4);
if (error)
break;
ref[i].x = 0.5F * width + x;
ref[i].y = 0.5F * height + y;
ref[i].width = sqrt(0.5F * (width * width + height * height));
ref[i].found = 0;
ref[i].neghbors = 0; //in the new cascade, where to get the neighbors?
}
vector<Rect> obj_detectados;
Rect retang;
if (!error) {
totaltime -= time(0);
cascade.detectMultiScale(img, obj_detectados, scale_factor, 4, 0
//|CV_HAAR_FIND_BIGGEST_OBJECT
// |CV_HAAR_DO_ROUGH_SEARCH
| CV_HAAR_SCALE_IMAGE, Size(25, 15));
totaltime += time(0);
if (obj_detectados.size() == 0) {
detcount = 0;
} else {
detcount = obj_detectados.size();
}
det = (detcount > 0) ?
((ObjectPos*) cvAlloc(detcount * sizeof(*det))) : NULL;
hits = missed = falseAlarms = 0;
for (vector<Rect>::const_iterator r = obj_detectados.begin();
r != obj_detectados.end(); r++, i++) {
Point r1, r2;
r1.x = (r->x);
r1.y = (r->y);
r2.x = (r->x + r->width);
r2.y = (r->y + r->height);
retang.x = r1.x;
retang.y = r1.y;
retang.width = abs(r2.x - r1.x);
retang.height = abs(r2.y - r1.y);
if (saveDetected) {
rectangle(img, retang, Scalar(0, 0, 255), 3, CV_AA);
}
det[i].x = 0.5F*r->width + r->x;
det[i].y = 0.5F*r->height + r->y;
det[i].width = sqrt(0.5F * (r->width * r->width
+ r->height * r->height));
det[i].neghbors = 1; // i don't know if it will work...
// det[i].neghbors = r.neighbors; --- how to do it in the new version??
found = 0;
for (j = 0; j < refcount; j++) {
distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
(det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
//cout << distance << endl;
if( (distance < ref[j].width * maxPosDiff) &&
(det[i].width > ref[j].width / maxSizeDiff) &&
(det[i].width < ref[j].width * maxSizeDiff) )
{
ref[j].found = 1;
ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
found = 1;
}
}
if (!found) {
falseAlarms++;
neg[MIN(det[i].neghbors, rocsize - 1)]++;
//neg[MIN(0, rocsize - 1)]++;
}
}
//imshow("teste", img);
if (saveDetected) {
//strcpy(detfilename, detname);
//strcat(detfilename, filename);
//strcpy(filename, detfilename);
imwrite(fullname, img);
//cvvSaveImage(fullname, img);
}
for (j = 0; j < refcount; j++) {
if (ref[j].found) {
hits++;
//pos[MIN(0, rocsize - 1)]++;
pos[MIN(ref[j].neghbors, rocsize - 1)]++;
} else {
missed++;
}
}
totalHits += hits;
totalMissed += missed;
totalFalseAlarms += falseAlarms;
printf("|%32.64s|%6d|%6d|%6d|\n", filename, hits, missed,
falseAlarms);
//printf("+--------------------------------+------+------+------+\n");
fprintf(resultados, "|%32.64s|%6d|%6d|%6d|\n", filename, hits,
missed, falseAlarms);
//fprintf(resultados,
// "+--------------------------------+------+------+------+\n");
fflush(stdout);
if (det) {
cvFree( &det);
det = NULL;
}
} /* if( !error ) */
//char c = (char) waitKey(10);
// if (c == 27)
// exit(0);
cvFree( &ref);
}
fclose(info);
printf("|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits, totalMissed,
totalFalseAlarms);
fprintf(resultados, "|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits,
totalMissed, totalFalseAlarms);
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//printf("Number of stages: %d\n", nos);
//printf("Number of weak classifiers: %d\n", numclassifiers[nos - 1]);
printf("Total time: %f\n", totaltime);
fprintf(resultados, "Total time: %f\n", totaltime);
/* print ROC to stdout */
for (i = rocsize - 1; i > 0; i--) {
pos[i - 1] += pos[i];
neg[i - 1] += neg[i];
}
//fprintf(stderr, "%d\n", nos);
for (i = 0; i < rocsize; i++) {
fprintf(stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
((float) pos[i]) / (totalHits + totalMissed),
((float) neg[i]) / (totalHits + totalMissed));
}
cvFree( &pos);
cvFree( &neg);
}
return 0;
}
My doubt is about the det[i].neghbors = r.neighbors; in the old performance.cpp. How I retrieve the neighbors in this new version?
Anyone could help me to convert opencv_performance to run the new cascades from opencv_traincascade?
Many thanks!