/* CFLoadFromDIB loads image from Windows DIB */ CF_ERROR __EXPORT_TYPE CFLoadFromDIB( CF_IMAGE hImage, CF_BMP info, BYTE* DIBPixels ) { CF_ERROR status = CF_SUCCESS; TLFImage* image = (TLFImage*)hImage; if(image == NULL) { status = CFF_INVALID_HANDLE; return status; } awpImage* img = NULL; BITMAPINFO lInfo; memcpy( &lInfo, &info, sizeof(CF_BMP) ); if( awpDIBToImage(&lInfo, DIBPixels, &img)!= AWP_OK ) { status = CFF_INVALID_DIB; return status; } try { image->SetImage( img ); } catch (...) { status = CFCR_NOT_ENOUGH_MEMORY; awpReleaseImage(&img); return status; } awpReleaseImage(&img); return status; }
/** * \brief Convert template to SClassInfo * \param pTemplate pointer to template * \param pInfo pointer to SClassInfo * \return FVC_OK if success, error code in other case */ int fvcTemplateToClassInfo(FvcTemplate* pTemplate, SClassInfo* pInfo) { int w,h, i, j; float* fdata; int Result = FVC_OK; Result = _fvcCheckTemplate(pTemplate); if (Result != FVC_OK) return Result; w = pTemplate->nVectorWidth; h = pTemplate->nVectorHeight; pInfo->m_nCount = pTemplate->nNumVectors-1; pInfo->m_pAverage = NULL; pInfo->m_pVectors = NULL; if (awpCreateImage(&pInfo->m_pAverage, (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT) != AWP_OK) return FVC_OUTOFMEMORY; pInfo->m_pVectors = (awpImage**)malloc(pInfo->m_nCount*sizeof(awpImage*)); if (pInfo->m_pVectors == NULL) { awpReleaseImage(&pInfo->m_pAverage); return FVC_OUTOFMEMORY; } for (i = 0; i < pInfo->m_nCount; i++) { if (awpCreateImage(&pInfo->m_pVectors[i], (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT)!= AWP_OK) { // cleanup for (j = 0; j < i; j++) awpReleaseImage(&pInfo->m_pVectors[j]); awpReleaseImage(&pInfo->m_pAverage); free(pInfo->m_pVectors); return FVC_OUTOFMEMORY; } // copy eigen vector fdata = pTemplate->pVectors + i*w*h; memcpy(pInfo->m_pVectors[i]->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); } fdata = pTemplate->pVectors + (pTemplate->nNumVectors-1)*w*h; memcpy(pInfo->m_pAverage->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); if( pTemplate->nDataSize == (pTemplate->nNumVectors*(w*h+1)-1)*sizeof(float) ) { fdata += w*h; pInfo->m_eigVals = (float*)malloc(pInfo->m_nCount*sizeof(float)); memcpy( pInfo->m_eigVals, (AWPBYTE*)fdata, pInfo->m_nCount*sizeof(float) ); } else pInfo->m_eigVals = NULL; return Result; }
FACE_API HRESULT facetrackProcess(HANDLE hModule, int width, int height, int bpp, unsigned char* data, TVAFace* result, int* num) { TheFace* p = (TheFace*)hModule; if (p->size != sizeof(TheFace)) return E_FAIL; awpImage* tmp = NULL; awpCreateGrayImage(&tmp, width, height, bpp, data); p->f->SetSourceImage(tmp, true); TLFSemanticImageDescriptor* d = p->f->GetSemantic(); int n = d->GetCount() > p->max_objects ? p->max_objects : d->GetCount(); *num = n; for (int i = 0; i < n; i++) { TLFDetectedItem* di = d->GetDetectedItem(i); if (di != NULL) { awpRect rr = di->GetBounds()->GetRect(); UUID id; di->GetId(id); memcpy(&result[i].id, &id, sizeof(UUID)); result[i].racurs = di->GetRacurs(); result[i].XPos = rr.left; result[i].YPos = rr.top; result[i].Width = rr.right - rr.left; result[i].Height = rr.bottom - rr.top; } } awpReleaseImage(&tmp); return S_OK; }
float CNCCPTrackCompare::Compare() { if (this->m_masterData.GetNumImages() > 0 && this->m_checkData.GetNumImages() > 0) { this->m_numDistances = this->m_checkData.GetNumImages(); if (this->m_distances != NULL) { free (this->m_distances); this->m_distances = NULL; } this->m_distances = (float*)malloc(this->m_numDistances* sizeof(float)); for (int i = 0; i < this->m_numDistances;i++) { awpImage* img = m_pcheck->GetImage(i); awpImage* pimg = this->m_precise.NormImage(img); this->m_distances[i] = Distance(pimg);//rand() % 100; awpReleaseImage(&pimg); } //min distance float min_distance = this->m_distances[0]; float sum = 0; for (int i = 0; i < m_numDistances; i++) { if (min_distance > this->m_distances[i]) min_distance = this->m_distances[i]; sum += this->m_distances[i]; } return sum /this->m_numDistances; // return min_distance; } return 0; }
bool CPCATrackCompare::LoadCheckTrack(const char* lpFileName) { bool res = CNCCPTrackCompare::LoadCheckTrack(lpFileName); if (res) { _AWP_SAFE_RELEASE_(m_pCheck) if (awpCreateImage(&m_pCheck, this->m_pTemplate->nNumVectors-1, this->m_pcheck->GetNumImages(), 1, AWP_FLOAT) != AWP_OK) return false; AWPFLOAT* pix = (AWPFLOAT*)m_pCheck->pPixels; for (int i = 0; i < this->m_pcheck->GetNumImages(); i++) { awpImage* img = this->m_pcheck->GetImage(i); awpImage* pimg = this->m_precise.NormImage(img); if (pimg) { fvcGetDecompositionCoeff(this->m_pTemplate , pimg, pix); pix+= this->m_pCheck->sSizeX; awpReleaseImage(&pimg); } } } return res; }
//--------------------------------------------------------------------------- void __fastcall TDIBImage::SaveToFile(const AnsiString Filename) { awpImage *image = NULL; GetAWPImage( &image ); awpSaveImage( Filename.c_str(), image ); awpReleaseImage( &image ); }
TSymptom::~TSymptom() { // dummy if (m_pPCATemplate != NULL) fvcFreeTemplate(&m_pPCATemplate); for (int i = 0; i < c_nMaxNumTrainig; i++) if (m_ppSamples != NULL) awpReleaseImage(&m_ppSamples[i]); free (m_ppSamples); }
float CNCCPTrackCompare::Distance(awpImage* img) { double result = 0; awpImage* img1 = m_pmaster->GetImage(0); awpImage* pimg1 = m_precise.NormImage(img1); awpDistance(img, pimg1, AWP_DIST_NCC, &result); awpReleaseImage(&pimg1); double minresult = 1 - result; for (int i = 1; i < this->m_pmaster->GetNumImages(); i++) { img1 = m_pmaster->GetImage(i); pimg1 = m_precise.NormImage(img1); awpDistance(img, pimg1, AWP_DIST_NCC, &result); awpReleaseImage(&pimg1); if (1 - result < minresult) minresult = 1 - result; } return minresult; }
int main(void) { awpImage* image = NULL; awpCreateImage(&image, 256, 256, 1, AWP_BYTE); awpSaveImage("test.awp", image); awpReleaseImage(&image); return 0; }
//--------------------------------------------------------------------------- void __fastcall TDIBImage::LoadFromFile(const AnsiString Filename) { awpImage *image = NULL; if ( awpLoadImage(Filename.c_str(), &image) != AWP_OK ) return; unsigned char *pDIB = (unsigned char *)::GlobalLock( (HGLOBAL)m_DIBPixels ); awpImageToDIB( image, &m_DIBInfo, &(void *)pDIB, true ); awpReleaseImage(&image); ::GlobalUnlock( (HGLOBAL)m_DIBPixels ); }
int fvcFreeClassInfo(SClassInfo* pInfo) { int Result = FVC_OK; if (pInfo == NULL) FVC_INVALIDARG; for (int i = 0; i < pInfo->m_nCount; i++) { if (pInfo->m_pVectors[i] != NULL) awpReleaseImage(&pInfo->m_pVectors[i]); } free(pInfo->m_pVectors); pInfo->m_pVectors = NULL; pInfo->m_nCount = 0; if (pInfo->m_pAverage != NULL) awpReleaseImage(&pInfo->m_pAverage); pInfo->m_pAverage = NULL; if( pInfo->m_eigVals!=NULL ) free( pInfo->m_eigVals ); return Result; }
TInternalFaceTracker::~TInternalFaceTracker() { if (this->m_htracker != NULL) { awpmflowRelease(this->m_htracker); this->m_htracker = NULL; } if (m_prevImage != NULL) { awpReleaseImage(&m_prevImage); m_prevImage = NULL; } }
/*сравнивает вектор с шаблоном*/ static void _fvcCompareVectors(awpImage* img, SClassInfo* class_info, int iCompareType, FvcTemplate* tmpl) { float* DecompCoeff = NULL; awpImage* reconstruction = NULL; class_info->m_dblDistance = 1; /* awpCreateImage(&reconstruction,img->sSizeX, img->sSizeY, 1, AWP_BYTE); */ DecompCoeff = (float*)malloc(class_info->m_nCount*sizeof(float)); // we shall find coef. projection of the initial image on // space of own vectors // differently we shall spread out the initial image awpEigenDecomposite(img, class_info->m_nCount,class_info->m_pVectors,class_info->m_pAverage,DecompCoeff); if (img->dwType == AWP_BYTE) { fvcBuildReconstruction(tmpl, DecompCoeff, &reconstruction); } else if (img->dwType == AWP_FLOAT) { fvcBuildReconstructionFloat(tmpl, DecompCoeff, &reconstruction); } // awpEigenProjection(class_info->m_nCount,class_info->m_pVectors,DecompCoeff,class_info->m_pAverage,reconstruction); #ifdef _DEBUG awpSaveImage("src.jpg", img); awpSaveImage("reconstruct.jpg", reconstruction); #endif AWPBYTE bThreshold = 100; switch( iCompareType ) { case FVC_COMPARE_EUCLID: class_info->m_dblDistance = _fvcEuclidDistance(img, reconstruction); break; case FVC_COMPARE_SEGMENTED: class_info->m_dblDistance = _fvcSegmentedDistance(img, reconstruction, bThreshold); break; case FVC_COMPARE_EUCLID_NORM: class_info->m_dblDistance = _fvcEuclidDistanceNorm(img, reconstruction); break; case FVC_COMPARE_CORRELATION: class_info->m_dblDistance = _fvcCorrelationCoeff(img, reconstruction); break; default: class_info->m_dblDistance = _fvcEuclidDistance(img, reconstruction); } free(DecompCoeff); awpReleaseImage(&reconstruction); }
TLFRect* TLFCarPredictor::Predict(ILFDetectEngine* engine) { if (m_pPredicted != NULL) { delete m_pPredicted; m_pPredicted = NULL; } TLFTileScaleScanner scanner(36, 24, 2,5, 1.1, 90); awpImage* _img = NULL; _img = engine->GetDetector(0)->GetImage()->GetImage(); scanner.Scan(_img->sSizeX, _img->sSizeY); AWPDOUBLE max_dist = 0; awpRect max_rect; for (int i = 0; i < scanner.GetFragmentsCount(); i++) { awpRect r1 = scanner.GetFragmentRect(i); double overlap = m_rect.RectOverlap(r1); if (overlap > 0.5) { awpImage* test = NULL; awpCopyRect(_img, &test, &r1); awpResize(test, 36,24); awpConvert(test, AWP_CONVERT_3TO1_BYTE); // double d; awpDistance(m_image, test, AWP_DIST_NCC,&d); if (max_dist < d) { max_dist = d; max_rect = r1; } awpReleaseImage(&test); } } if (max_dist > 0.5) { TLFRect* r_result = new TLFRect(); r_result->SetRect(max_rect); m_pPredicted = r_result; m_rect.SetRect(r_result->GetRect()); } else return NULL; }
// загрузака растрового изображения из неструктуированной памяти. CF_ERROR __EXPORT_TYPE CFLoadFromDump(CF_IMAGE hImage, CF_WORD width, CF_WORD height, CF_WORD bpp, CF_BYTE* pixels, CF_WORD line_width) { CF_ERROR status = CF_SUCCESS; // получение указателя на изображение TLFImage* image = (TLFImage*)hImage; if(image == NULL) { status = CFF_INVALID_HANDLE; return status; } // проверка указателя на пиксели if (pixels == NULL) { status = CFF_INVALID_PARAM; return status; } // проверка числа битов на пиксель if (bpp != 8 && bpp != 24) { status = CFF_INVALID_PARAM; return status; } awpImage* tmp = NULL; if (awpCreateImage(&tmp, width, height, bpp == 8?1:3, AWP_BYTE) != AWP_OK) { status = CFCR_NOT_ENOUGH_MEMORY; return status; } // копирование пикселей в изображение tmp int bufsize = width*(bpp == 8 ? 1:3);// число байт в строке, с возможным выравниваием BYTE* b = (BYTE*)tmp->pPixels; for (int i = 0; i < height; i++) { memcpy(b, pixels, bufsize); b+= bufsize; pixels += line_width; } image->SetImage(tmp); awpReleaseImage(&tmp); return status; }
static double _fvcSegmentedDistance(awpImage* img1, awpImage* img2, AWPBYTE bThreshold) { AWPBYTE* b1; AWPBYTE* b2; AWPBYTE* d; int i; double result = -1; int size = img1->sSizeX*img1->sSizeY; if (img1 == NULL || img2 == NULL) return result; if (img1->sSizeX != img2->sSizeX && img1->sSizeY != img2->sSizeY) return result; if (img1->dwType != img2->dwType) return result; if (img1->dwType != AWP_BYTE) return result; if (size == 0) return result; result = 0; b1 = (AWPBYTE*)img1->pPixels; b2 = (AWPBYTE*)img2->pPixels; awpImage* distance = NULL; awpCreateImage(&distance,img1->sSizeX, img1->sSizeY, 1, AWP_BYTE); d = (AWPBYTE*)distance->pPixels; for (i = 0; i < size; i++) d[i] = abs(b1[i]-b2[i]);// < bThreshold) ? 1 : 0; for (i = 0; i < size; i++) result += (d[i] * ((double)b1[i]-(double)b2[i])*((double)b1[i]-(double)b2[i])); result /= size; result /= 255*255; awpReleaseImage(&distance); return result; }
FACE_API HRESULT faceProcess(HANDLE hModule, int width, int height, int bpp, unsigned char* data, TVAFace* result, int* num) { TheFace* p = (TheFace*)hModule; if (p->size != sizeof(TheFace)) return E_FAIL; #ifdef _DEBUG printf("bpp = %i \n", bpp); #endif awpImage* tmp = NULL; awpCreateGrayImage(&tmp, width, height, bpp, data); #ifdef _DEBUG awpSaveImage("out.awp", tmp); #endif p->f->SetSourceImage(tmp, true); int n = p->f->GetItemsCount(); *num =0; for (int i = 0; i < n; i++) { TLFDetectedItem* di = p->f->GetItem(i); if (di != NULL) { awpRect rr = di->GetBounds()->GetRect(); UuidCreate(&result[i].id); result[i].racurs = di->GetRacurs(); result[i].XPos = rr.left; result[i].YPos = rr.top; result[i].Width = rr.right - rr.left; result[i].Height = rr.bottom - rr.top; (*num)++; } } awpReleaseImage(&tmp); return S_OK; }
// функция обработки нового изображения void TSymptom::SetImage(awpImage* pImage) { if (pImage == NULL) return; awpImage* src = NULL; awpCopyImage(pImage, &src); m_source_image.SetImage(pImage); awpConvert(src, AWP_CONVERT_3TO1_BYTE); AWPWORD NewWidth = (AWPWORD)(m_ResizeFactor*pImage->sSizeX); AWPWORD NewHeight = (AWPWORD)(m_ResizeFactor*pImage->sSizeY); if (m_first_time) { // установим новые параметры площади m_source_width = pImage->sSizeX; m_source_height = pImage->sSizeY; SetMinBlobSquare(m_min_blob_square); SetMaxBlobSquare(m_max_blob_square); m_ResizeFactor = sqrt(c_flProcessingArea/(m_source_width*m_source_height)); //awpRect roiRect; //roiRect.left = 10; //roiRect.right = this->m_source_width - 10; //roiRect.top = 10; //roiRect.bottom = this->m_source_height -10; //SetRoiRect(roiRect); NewWidth = (AWPWORD)(m_ResizeFactor*pImage->sSizeX); NewHeight = (AWPWORD)(m_ResizeFactor*pImage->sSizeY); #ifdef _DEBUG awpSaveImage("bg.jpg", src); #endif awpResize(src, (AWPWORD)NewWidth, (AWPWORD)NewHeight); awpConvert(src, AWP_CONVERT_TO_FLOAT); m_background.SetImage(src); awpImage* src1 = m_background.GetImage(); awpGaussianBlur(src, src1,2); m_background2.SetImage(src); awpImage* pb2 = m_background2.GetImage(); float* b2 = (float*)pb2->pPixels; for (int i = 0; i < pb2->sSizeX*pb2->sSizeY; i++) b2[i] *=b2[i]; awpImage* tmp = NULL; awpCreateImage(&tmp, src->sSizeX, src->sSizeY, 1, AWP_BYTE); // SetImage делает копию изображения tmp внутри объекта m_diff.SetImage(tmp); m_binary.SetImage(tmp); m_binary_source.SetImage(tmp); m_diff1.SetImage(tmp); m_prev.SetImage(tmp); awpReleaseImage(&tmp); this->SetRoiRect(m_roiRect); fvcCreateTemplate(&m_pPCATemplate, src->sSizeX, src->sSizeY, 10); m_first_time = false; m_start_time = clock() / CLOCKS_PER_SEC ; m_current_time = m_start_time; } else if (NewWidth != m_background.GetImage()->sSizeX || NewHeight != m_background.GetImage()->sSizeY) { Reset(); goto cleanup; } else { m_NumFrames++; awpResize(src, (AWPWORD)NewWidth, (AWPWORD)NewHeight); //обработка времени float t = clock() / CLOCKS_PER_SEC; m_current_dt = t - m_current_time; m_current_time = t; // todo: если промежуток времени между кадрами превысил порог // сбрасываем фон и все объекта и начинаем наблюдения снова. if (/*m_current_dt > c_flMinT*/false) { Reset(); goto cleanup; } else { m_current.SetImage(src); awpImage* src1 = m_current.GetImage(); awpGaussianBlur(src, src1, 2); #ifdef _DEBUG // m_current.SaveImage("Gauss.jpg"); #endif } // обработка изображения. Process(); m_prev.SetImage(src); } cleanup: awpReleaseImage(&src); }
int TInternalFaceTracker::SetImage(awpImage* pImage) { if (this->m_model == NULL || this->m_needInit) { this->Init(pImage); return 0; } awpImage* copy = NULL; awpCopyImage(pImage, ©); awpConvert(copy, AWP_CONVERT_3TO1_BYTE); //выполняется поиск лиц. int num = TInternalFaceDetector::SetImage(copy); //выполняется сопровождение найденных лиц. this->track(copy); //расфасовка if ( num > 0) { // для каждого найденного лица // обновляется существующий массив лиц for (int i =0; i < num; i++) { awpRect r1 = this->m_objects[i].rect; for (int j = 0; j < m_faces.GetCount(); j++) { IFaceObject* o = (IFaceObject*)m_faces.Get(j); awpRect r2; memcpy(&r2, o->bounds(), sizeof(awpRect)); if (_awpRectsOverlap(r1, r2) > 0) { o->update(copy, &r1); this->m_objects[i].hasObject = false; } } } //формируется событие найдено новое лицо for (int i = 0; i < num; i++) { if (this->m_objects[i].hasObject) { TFlowFaceObject* o = new TFlowFaceObject(this->m_next_id++, copy, &this->m_objects[i].rect); m_faces.Add(o); //todo: событие лицо найдено. if (this->faceFound != NULL) this->faceFound(o->GetImage(0), o->id()); } } } // проверяется состояние существующего массива лиц. // если значение переменной health < 0 объект удаляется из // наблюдения. for (int i = m_faces.GetCount() -1 ; i >= 0; i--) { IFaceObject* o = (IFaceObject*)m_faces.Get(i); if (o->health() < 0) { string strFileName = ""; if (this->m_save_tracks) { strFileName = this->m_outPath; strFileName += "\\"; strFileName += newUUID(); strFileName += ".awp"; o->SaveTrack(strFileName.c_str()); } //объект потерян. if (this->saveTrack != NULL) this->saveTrack(strFileName.c_str(), o->id()); m_faces.Delete(i); } else { // Объкт изменил местоположение if (this->facePos != NULL) { awpRect* r = o->bounds(); if (r != NULL) { AWPDOUBLE v, vv, vvv; awpDetectItem item; item.rect = *r; item.hasObject = true; awpPoint pp; pp.X = (item.rect.left + item.rect.right) / 2; pp.Y = item.rect.top; awpImageYHToLength(&camera, copy, item.rect.top, 1800, &vv); awpImageObjectHWidth(&camera, copy, &item.rect, 1800, &v); awpImagePointToShiftHX(&camera, copy, &pp, 1800, &vvv); item.Distance = vv; item.Width = v; item.Shift = vvv; item.Height = 1800; this->facePos( NULL, &item, o->id()); } } } } awpReleaseImage(©); return m_faces.GetCount(); }
/*вычисление разницы между моделью фона и вновь пришедщим изображением*/ void TSymptom::AbsDiff() { awpImage* pbg = m_background.GetImage(); awpImage* pbg2 = m_background2.GetImage(); awpImage* pcr = m_current.GetImage(); awpImage* pdf = m_diff.GetImage(); awpImage* pdiff1 = m_diff1.GetImage(); awpImage* pprev = m_prev.GetImage(); float* bg = (float*)pbg->pPixels; float* bg2 = (float*)pbg2->pPixels; BYTE* c = (BYTE*)pcr->pPixels; BYTE* d = (BYTE*)pdf->pPixels; BYTE* d1 = (BYTE*)pdiff1->pPixels; BYTE* pp = (BYTE*)pprev->pPixels; int thr = m_FGBGThreshold*255; if (m_fgbg_algorytm == fgbgPCA) { if (this->m_NumFrames < m_NumFramesToTraining) { awpCopyImage(pcr, &m_ppSamples[m_NumFrames-1]); } else if (this->m_NumFrames == m_NumFramesToTraining) { fvcBuildTemplate(this->m_ppSamples, c_nMaxNumTrainig, m_pPCATemplate); #ifdef _DEBUG fvcSaveTemplateAsImage("template.jpg", m_pPCATemplate); #endif } else { awpImage* pReconstr = NULL; fvcGetReconstruction(m_pPCATemplate, pcr, &pReconstr); BYTE* rr = (BYTE*)pReconstr->pPixels; #ifdef _DEBUG awpSaveImage("tmpl_reconst.jpg", pReconstr); #endif int i = 0; for (int y= 0; y < pcr->sSizeY; y++) { for (int x = 0; x < pcr->sSizeX; x++) { if (x > m_insideRoi.left && x < m_insideRoi.right && y > m_insideRoi.top && y < m_insideRoi.bottom) { d[i] = abs(c[i] - rr[i]) > thr ? 255 : 0; } else d[i] = 0; i++; } } awpReleaseImage(&pReconstr); } } else if (m_fgbg_algorytm == fgbgSG) { int i = 0; for (int y= 0; y < pbg->sSizeY; y++) { for (int x = 0; x < pbg->sSizeX; x++) { if (x > m_insideRoi.left && x < m_insideRoi.right && y > m_insideRoi.top && y < m_insideRoi.bottom) { bg[i] += c[i]; bg2[i] += c[i]*c[i]; float m = bg[i] / (float)(m_NumFrames + 1); float s2 = bg2[i] / (float)(m_NumFrames + 1); s2 -= m*m; s2 += 0.00001; float s = sqrt(s2) + 0.00001; //float pr = (1 / (s*sqrt(2*3.14)))*exp(-(c[i] - m)*(c[i] - m) / (2*s2)); //if ((c[i] - m) == 0) // d[i] = 0; //else // d[i] = pr > 0.004 ? 0 : 255; //d[i] = abs(c[i] - m) > 4*s ? 255 : 0; d[i] = abs(c[i] - m) > thr ? 255 : 0; } else d[i] = 0; i++; } } } }
int fvcGetDecompositionCoeff(FvcTemplate* pTemplate, awpImage* pImage, float* pCoeff) { int Result = FVC_OK; float* DecompCoeff = NULL; int result,res,i,w,h,j; float* fdata; SClassInfo class_info; if (pImage == NULL) return FVC_INVALIDARG; result = _fvcCheckTemplate(pTemplate); if (result != FVC_OK) return result; if (pImage->sSizeX != pTemplate->nVectorWidth || pImage->sSizeY != pTemplate->nVectorHeight) return FVC_INVALIDARG; // prepare eigen vectors and average object class_info.m_nCount = pTemplate->nNumVectors-1; class_info.m_pAverage = NULL; class_info.m_pVectors = NULL; w = pTemplate->nVectorWidth; h = pTemplate->nVectorHeight; res = awpCreateImage(&class_info.m_pAverage, (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) return FVC_OUTOFMEMORY; class_info.m_pVectors = (awpImage**)malloc(class_info.m_nCount*sizeof(awpImage*)); if (class_info.m_pVectors == NULL) { awpReleaseImage(&class_info.m_pAverage); return FVC_OUTOFMEMORY; } for (i = 0; i < class_info.m_nCount; i++) { // create eigen vector res = awpCreateImage(&class_info.m_pVectors[i], (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) { // cleanup for (j = 0; j < i; j++) awpReleaseImage(&class_info.m_pVectors[j]); awpReleaseImage(&class_info.m_pAverage); free(class_info.m_pVectors); return FVC_OUTOFMEMORY; } // copy eigen vector fdata = pTemplate->pVectors + i*w*h; memcpy(class_info.m_pVectors[i]->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); } fdata = pTemplate->pVectors + (pTemplate->nNumVectors-1)*w*h; memcpy(class_info.m_pAverage->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); // class_info.m_eigVals = (float*)malloc(class_info.m_nCount*sizeof(float)); // fdata += w*h; // memcpy(class_info.m_eigVals, (BYTE*)fdata, class_info.m_nCount*sizeof(float)); DecompCoeff = (float*)malloc(class_info.m_nCount*sizeof(float)); // we shall find coef. projection of the initial image on // space of own vectors // differently we shall spread out the initial image awpEigenDecomposite(pImage, class_info.m_nCount,class_info.m_pVectors,class_info.m_pAverage,DecompCoeff); memcpy(pCoeff, DecompCoeff, class_info.m_nCount*sizeof(float)); // for( i = 0; i < class_info.m_nCount; i++ ) // pCoeff[i] *= (class_info.m_eigVals)[i]; free(DecompCoeff); // cleanup awpReleaseImage(&class_info.m_pAverage); for (j = 0; j < class_info.m_nCount; j++) awpReleaseImage(&class_info.m_pVectors[j]); free(class_info.m_pVectors); return Result; }
/*========================================================================== Function: - fvcSaveTemplate Purpose: - Save tempalate as tiled awp image Arguments: - pFileName : file name - pTemplate : fvc template Return values: ============================================================================*/ int fvcSaveTemplateAsImage(const char* pFileName, FvcTemplate*pTemplate) { // variables AWPBYTE* src; // pointers to pixels AWPBYTE* dst; int n; AWPWORD i,w,h; // helpers AWPWORD ht,wt,j,k; // helpers too int res = AWP_OK; // result of awpipl's calls int result = FVC_OK; // result of this awpImage* pTile = NULL; // tiled image awpImage* pGray = NULL; // temprary grayscale awpImage** pObjects = NULL; // array of eigen objects awpImage* pAverage = NULL; // average object // arguments if (pFileName == NULL || pTemplate == NULL) return FVC_INVALIDARG; result = _fvcCheckTemplate(pTemplate); if (result != FVC_OK) return result; w = pTemplate->nVectorWidth; h = pTemplate->nVectorHeight; n = pTemplate->nNumVectors; // alloc memory for all objects res = awpCreateImage(&pAverage, w, h, 1, AWP_FLOAT); if (res != AWP_OK) return FVC_OUTOFMEMORY; pObjects = (awpImage**)malloc((pTemplate->nNumVectors - 1)*sizeof(awpImage*)); memset(pObjects, 0, (pTemplate->nNumVectors - 1)*sizeof(awpImage*)); if (pObjects == NULL) { result = FVC_OUTOFMEMORY; goto cleanup; } for (i = 0; i < n-1; i++) { res = awpCreateImage(&pObjects[i], w,h, 1, AWP_FLOAT); if (res != AWP_OK) { result = FVC_OUTOFMEMORY; goto cleanup; } } // convert template to awp images result = _fvcTemplate2Images(pTemplate, pAverage, pObjects, &n); if (result != FVC_OK) goto cleanup; // create tiled image ht = h; wt = w*n; res = awpCreateImage(&pTile, wt, ht, 1, AWP_BYTE); if (res != AWP_OK) { result = FVC_OUTOFMEMORY; goto cleanup; } // create temporary grayscale image res = awpCreateImage(&pGray, w,h, 1, AWP_BYTE); if (res != AWP_OK) { result = FVC_OUTOFMEMORY; goto cleanup; } _fvcConvertFloatAwp2GrayscaleAwp(pAverage, pGray); // save to tiled image average src = (AWPBYTE*)pGray->pPixels; dst = (AWPBYTE*)pTile->pPixels; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { dst[i*wt + j] = src[i*pGray->sSizeX + j]; } } // save all eigen objects to tiled image for (k = 0; k < n-1; k++) { _fvcConvertFloatAwp2GrayscaleAwp(pObjects[k], pGray); src = (AWPBYTE*)pGray->pPixels; dst = (AWPBYTE*)pTile->pPixels; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { dst[i*wt + (k+1)*pGray->sSizeX + j] = src[i*pGray->sSizeX + j]; } } } // uff!! tiled image was created save it! res = awpSaveImage(pFileName, pTile); if (res != AWP_OK) { result = FVC_CANNOTSAVE; goto cleanup; } cleanup: if (pTile != NULL) awpReleaseImage(&pTile); if (pGray != NULL) awpReleaseImage(&pGray); if (pAverage != NULL) awpReleaseImage(&pAverage); if (pObjects != NULL) { for (i = 0; i < n-1; i++) { if (pObjects[i] != NULL) awpReleaseImage(&pObjects[i]); } free (pObjects); } return result; }
/*========================================================================== Function: fvcCompare Purpose: сравнивает изображение и шаблон Arguments: pImage - изображение для сравнения pTemplate - шаблон для сравнения Error - расстояние между изображением и шаблоном iCompareType - свособ вычисления расстояния FVC_COMPARE_EUCLID - вычисляется евклидово расстояние между изображением и шаблоном FVC_COMPARE_SEGMENTED - вычисляется расстояние посегментно Return values: ============================================================================*/ int fvcCompare(awpImage* pImage, FvcTemplate* pTemplate, double* Error, int iCompareType) { int result,res,i,w,h,j; float* fdata; SClassInfo class_info; if (Error == NULL) return FVC_INVALIDARG; if (pImage == NULL) return FVC_INVALIDARG; result = _fvcCheckTemplate(pTemplate); if (result != FVC_OK) return result; if (pImage->sSizeX != pTemplate->nVectorWidth || pImage->sSizeY != pTemplate->nVectorHeight) return FVC_INVALIDARG; // prepare eigen vectors and average object class_info.m_nCount = pTemplate->nNumVectors-1; class_info.m_pAverage = NULL; class_info.m_pVectors = NULL; w = pTemplate->nVectorWidth; h = pTemplate->nVectorHeight; res = awpCreateImage(&class_info.m_pAverage, (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) return FVC_OUTOFMEMORY; class_info.m_pVectors = (awpImage**)malloc(class_info.m_nCount*sizeof(awpImage*)); if (class_info.m_pVectors == NULL) { awpReleaseImage(&class_info.m_pAverage); return FVC_OUTOFMEMORY; } for (i = 0; i < class_info.m_nCount; i++) { // create eigen vector res = awpCreateImage(&class_info.m_pVectors[i], (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) { // cleanup for (j = 0; j < i; j++) awpReleaseImage(&class_info.m_pVectors[j]); awpReleaseImage(&class_info.m_pAverage); free(class_info.m_pVectors); return FVC_OUTOFMEMORY; } // copy eigen vector fdata = pTemplate->pVectors + i*w*h; memcpy(class_info.m_pVectors[i]->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); } fdata = pTemplate->pVectors + (pTemplate->nNumVectors-1)*w*h; memcpy(class_info.m_pAverage->pPixels, (AWPBYTE*)fdata, w*h*sizeof(float)); _fvcCompareVectors(pImage, &class_info, iCompareType, pTemplate); *Error = class_info.m_dblDistance; // cleanup awpReleaseImage(&class_info.m_pAverage); for (j = 0; j < class_info.m_nCount; j++) awpReleaseImage(&class_info.m_pVectors[j]); free(class_info.m_pVectors); return FVC_OK; }
/*========================================================================== Function: Purpose: Arguments: Return values: ============================================================================*/ int fvcBuildTemplate(awpImage** ppImages, int count, FvcTemplate* pTemplate) { int result,num,i,w,h,j,r; float* pData; awpImage** eigenObjects = NULL; // eigen vectors awpImage* avg = NULL; // average object float* eigVals = NULL; // eigen values AWPRESULT res = AWP_OK; // check arguments if (ppImages == NULL) return FVC_INVALIDARG; if (count <= 0) return FVC_INVALIDARG; result = _fvcCheckTemplate(pTemplate); if (result != FVC_OK) return result; w = pTemplate->nVectorWidth; h = pTemplate->nVectorHeight; num = pTemplate->nNumVectors - 1; // alloc memory for eigen array eigenObjects = (awpImage**)malloc(num*sizeof(awpImage*)); if (eigenObjects == NULL) return FVC_OUTOFMEMORY; // alloc memory for objects for(i = 0; i < num; i++) { res = awpCreateImage(&eigenObjects[i],(AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) { // cleanup for (j = 0; j < i; j++) awpReleaseImage(&eigenObjects[j]); free(eigenObjects); return FVC_OUTOFMEMORY; } } // alloc memory for avrage image res = awpCreateImage(&avg, (AWPWORD)w, (AWPWORD)h, 1, AWP_FLOAT); if (res != AWP_OK) { // cleanup for (i = 0; i < num; i++) awpReleaseImage(&eigenObjects[i]); free(eigenObjects); return FVC_OUTOFMEMORY; } // alloc memory for eigen values eigVals = (float*)malloc(num*sizeof(float)); if (eigVals == NULL) { // cleanup for (i = 0; i < num; i++) awpReleaseImage(&eigenObjects[i]); free(eigenObjects); return FVC_OUTOFMEMORY; } r = awpCalcEigenObjects(num, ppImages, eigenObjects, 0.0001f, avg, eigVals); if (r != 0) { // cleanup for (i = 0; i < num; i++) awpReleaseImage(&eigenObjects[i]); free(eigenObjects); free(eigVals); return FVC_CANNOTBUILD; } // copy data to vectors and to average object for (i = 0; i < num; i++) { pData = pTemplate->pVectors + i*w*h; memcpy(pData, eigenObjects[i]->pPixels, h*w*sizeof(float)); } // copy average memcpy(pTemplate->pVectors + num*h*w, avg->pPixels, h*w*sizeof(float)); // copy eigen values if( pTemplate->nDataSize == (pTemplate->nNumVectors*(w*h+1)-1)*sizeof(float) ) { memcpy(pTemplate->pVectors + (num+1)*h*w, eigVals, num*sizeof(float)); } // cleanup for (i = 0; i < num; i++) awpReleaseImage(&eigenObjects[i]); free(eigenObjects); free(eigVals); awpReleaseImage(&avg); return FVC_OK; }
//--------------------------------------------------------------------------- void __fastcall TDetectorForm::DoDetectorInfo() { this->Series1->Clear(); ILFDetectEngine* e = Form1->Engine; TSCObjectDetector* d = (TSCObjectDetector*)e->GetDetector(0); int w = d->GetBaseWidth()*10; int h = d->GetBaseHeight()*10; awpImage* img = NULL; awpCreateImage(&img, w, h, 1, AWP_DOUBLE); double* pix = (double*)img->pPixels; for (int i = 0; i < d->GetStagesCount(); i++) { switch(this->ComboBox1->ItemIndex) { case 0: this->Series1->Add(d->GetSensorsCount(i)); break; case 1: this->Series1->Add(d->GetStageThreshold(i)); break; case 2: this->Series1->Add(d->GetStageWeight(i)); break; } } TLFObjectList* strongs = d->GetStrongs(); for (int i = 0; i < strongs->GetCount(); i++) { ILFStrong* s = (ILFStrong*)strongs->Get(i); if (ComboBox2->ItemIndex > 0 && ComboBox2->ItemIndex - 1 != i ) continue; for (int j = 0; j < s->GetCount(); j++) { ILFWeak* ww = (ILFWeak*)s->GetWeak(j); ILFFeature* f = ww->Fetaure(); awpRect r = f->GetRect(); r.left *= 10; r.top *= 10; r.right *= 10; r.bottom *= 10; if (this->CheckBox2->Checked) { for (int y = r.top; y < r.bottom; y++) { for (int x = r.left; x < r.right; x++) { if (this->CheckBox1->Checked) pix[x+y*w] += ww->Weight(); else pix[x+y*w] += 1; } } } else { //awpPoint p = TLFRect rect; rect.SetRect(r); awpPoint p = rect.Center(); awpRect r0; r0.left = p.X - 2; r0.top = p.Y - 2; r0.right = p.X+2; r0.bottom = p.Y + 2; if (this->CheckBox1->Checked) awpDrawRect(img, &r0, 0, ww->Weight(), 1); else awpDrawRect(img, &r0, 0, 1, 1); } } } awpConvert(img, AWP_CONVERT_TO_BYTE_WITH_NORM); this->FImage1->Bitmap->SetAWPImage(img); FImage1->BestFit(); awpReleaseImage(&img); }
//--------------------------------------------------------------------------- void __fastcall TDIBImage::SetWidth( int in_Width ) { if (in_Width == m_DIBInfo.bmiHeader.biWidth) return; if ( in_Width <= 0 ) { Clear(); return; } if ( in_Width == Width ) return; awpImage *src_image = NULL; awpImage *dst_image = NULL; unsigned char *pDIB = NULL; long size = 0; long w = 0; if ( m_DIBPixels == 0 ) { if ( awpCreateImage( &dst_image, in_Width, 1, 3, AWP_BYTE ) != AWP_OK ) return; } else { pDIB = (unsigned char *) ::GlobalLock( (HGLOBAL)m_DIBPixels ); if (awpDIBToImage( &m_DIBInfo, pDIB, &src_image ) != AWP_OK ) return; ::GlobalUnlock( (HGLOBAL)m_DIBPixels ); if ( in_Width > src_image->sSizeX ) { awpColor white_color; white_color.bRed = 255; white_color.bGreen = 255; white_color.bBlue = 255; awpPoint pnt; pnt.X = 0; pnt.Y = 0; awpCreateImage( &dst_image, in_Width, src_image->sSizeY, src_image->bChannels, src_image->dwType ); //awpFill( dst_image, &white_color ); awpFill( dst_image, 255 ); awpPasteRect( src_image, dst_image, pnt ); } else { awpRect rect; rect.top = 0; rect.bottom = src_image->sSizeY - 1; rect.left = 0; rect.right = in_Width; awpCopyRect( src_image, &dst_image, &rect ); } } Clear(); w = ((dst_image->sSizeX * 24 + 31)/32) * 4; size = w * dst_image->sSizeY * sizeof(unsigned char); m_DIBPixels = (HDIB) ::GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, size ); if ( m_DIBPixels == 0 ) { awpReleaseImage( &src_image ); awpReleaseImage( &dst_image ); return; } pDIB = (unsigned char *) ::GlobalLock( (HGLOBAL)m_DIBPixels ); awpImageToDIB( dst_image, &m_DIBInfo, &((void*)pDIB), true); ::GlobalUnlock( (HGLOBAL)m_DIBPixels ); awpReleaseImage( &src_image ); awpReleaseImage( &dst_image ); }