31#include <scolPlugin.h>
38#include <AR2/config.h>
39#include <AR2/imageFormat.h>
40#include <AR2/imageSet.h>
41#include <AR2/featureSet.h>
44#include <boost/filesystem.hpp>
48#define MIN_TRACKED_MARKER_SIZE 240
57 if (LoadRefDataSet(path, refDataSetPtr))
58 if (LoadFeatureSet(path, surfaceSetPtr))
64bool NFTDataLoader::LoadRefDataSet(boost::filesystem::path path, KpmRefDataSet** refDataSetPtr)
66 KpmRefDataSet *refDataSet = NULL;
70 if (path.empty() || !refDataSetPtr)
75 path.replace_extension(
".fset3");
76 fp = fopen(path.generic_string().c_str(),
"rb");
82 arMallocClear(refDataSet, KpmRefDataSet, 1);
84 if (fread(&(refDataSet->num),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
85 if (refDataSet->num <= 0)
goto bailBadRead;
87 arMalloc(refDataSet->refPoint, KpmRefData, refDataSet->num);
88 for (i = 0; i < refDataSet->num; i++)
90 if (fread(&(refDataSet->refPoint[i].coord2D),
sizeof(KpmCoord2D), 1, fp) != 1)
goto bailBadRead;
91 if (fread(&(refDataSet->refPoint[i].coord3D),
sizeof(KpmCoord2D), 1, fp) != 1)
goto bailBadRead;
92 if (fread(&(refDataSet->refPoint[i].featureVec),
sizeof(FreakFeature), 1, fp) != 1)
goto bailBadRead;
93 if (fread(&(refDataSet->refPoint[i].pageNo),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
94 if (fread(&(refDataSet->refPoint[i].refImageNo),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
97 if (fread(&(refDataSet->pageNum),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
98 if (refDataSet->pageNum <= 0)
100 refDataSet->pageInfo = NULL;
104 arMalloc(refDataSet->pageInfo, KpmPageInfo, refDataSet->pageNum);
105 for (i = 0; i < refDataSet->pageNum; i++)
107 if (fread(&(refDataSet->pageInfo[i].pageNo),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
108 if (fread(&(refDataSet->pageInfo[i].imageNum),
sizeof(
int), 1, fp) != 1)
goto bailBadRead;
110 j = refDataSet->pageInfo[i].imageNum;
111 arMalloc(refDataSet->pageInfo[i].imageInfo, KpmImageInfo, j);
113 if (fread(refDataSet->pageInfo[i].imageInfo,
sizeof(KpmImageInfo), j, fp) != j)
goto bailBadRead;
116 *refDataSetPtr = refDataSet;
124 kpmDeleteRefDataSet(&refDataSet);
130bool NFTDataLoader::LoadFeatureSet(boost::filesystem::path path, AR2SurfaceSetT** surfaceSetPtr)
133 AR2SurfaceSetT* surfaceSet = NULL;
136 if (path.empty() || !surfaceSetPtr)
141 arMalloc(surfaceSet, AR2SurfaceSetT, 1);
144 surfaceSet->contNum = 0;
145 arMalloc(surfaceSet->surface, AR2SurfaceT, surfaceSet->num);
147 for (i = 0; i < surfaceSet->num; i++)
149 surfaceSet->surface[i].imageSet = GetImageSet(path);
150 if (surfaceSet->surface[i].imageSet == NULL)
155 surfaceSet->surface[i].featureSet = ReadFeatureSet(path);
156 if (surfaceSet->surface[i].featureSet == NULL)
160 surfaceSet->surface[i].markerSet = NULL;
162 for (j = 0; j < 3; j++)
164 for (k = 0; k < 4; k++)
166 surfaceSet->surface[i].trans[j][k] = (j == k) ? 1.0f : 0.0f;
169 arUtilMatInvf((
const float(*)[4])surfaceSet->surface[i].trans, surfaceSet->surface[i].itrans);
170 surfaceSet->surface[i].jpegName = 0;
176 if (i < surfaceSet->num)
179 *surfaceSetPtr = surfaceSet;
183 if (surfaceSet && surfaceSet->surface)
184 free(surfaceSet->surface);
194AR2ImageSetT* NFTDataLoader::GetImageSet(boost::filesystem::path path)
196 AR2JpegImageT *jpgImage;
197 AR2ImageSetT *imageSet;
202 path.replace_extension(
".iset");
203 if ((fp = fopen(path.generic_string().c_str(),
"rb")) == NULL)
208 arMalloc(imageSet, AR2ImageSetT, 1);
209 if (fread(&(imageSet->num),
sizeof(imageSet->num), 1, fp) != 1 || imageSet->num <= 0)
215 arMalloc(imageSet->scale, AR2ImageT*, imageSet->num);
216 arMalloc(imageSet->scale[0], AR2ImageT, 1);
218 jpgImage = ar2ReadJpegImage2(fp);
219 if (jpgImage == NULL || jpgImage->nc != 1)
221 free(imageSet->scale[0]);
222 free(imageSet->scale);
225 if (jpgImage == NULL)
228 return LoadRawImageSet(fp);
235 imageSet->scale[0]->xsize = jpgImage->xsize;
236 imageSet->scale[0]->ysize = jpgImage->ysize;
237 imageSet->scale[0]->dpi = jpgImage->dpi;
238 imageSet->scale[0]->imgBW = jpgImage->image;
243 fseek(fp, (
long)(-(
int)
sizeof(dpi)*(imageSet->num - 1)), SEEK_END);
244 for (i = 1; i < imageSet->num; i++)
246 if (fread(&dpi,
sizeof(dpi), 1, fp) != 1)
248 for (k1 = 0; k1 < i; k1++)
250 free(imageSet->scale[k1]->imgBW);
251 free(imageSet->scale[k1]);
253 free(imageSet->scale);
257 imageSet->scale[i] = GetImageLayer(imageSet->scale[0], dpi);
258 if (imageSet->scale[i] == NULL)
260 for (k1 = 0; k1 < i; k1++)
262 free(imageSet->scale[k1]->imgBW);
263 free(imageSet->scale[k1]);
265 free(imageSet->scale);
281AR2ImageSetT* NFTDataLoader::LoadRawImageSet(FILE* fp)
283 AR2ImageSetT* imageSet;
286 arMalloc(imageSet, AR2ImageSetT, 1);
288 if (fread(&(imageSet->num),
sizeof(imageSet->num), 1, fp) != 1 || imageSet->num <= 0)
293 arMalloc(imageSet->scale, AR2ImageT*, imageSet->num);
294 for (i = 0; i < imageSet->num; i++)
296 arMalloc(imageSet->scale[i], AR2ImageT, 1);
299 for (i = 0; i < imageSet->num; i++)
301 if (fread(&(imageSet->scale[i]->xsize),
sizeof(imageSet->scale[i]->xsize), 1, fp) != 1)
303 for (k = 0; k < i; k++)
305 free(imageSet->scale[k]->imgBW);
307 for (k = 0; k < imageSet->num; k++) free(imageSet->scale[k]);
310 if (fread(&(imageSet->scale[i]->ysize),
sizeof(imageSet->scale[i]->ysize), 1, fp) != 1)
312 for (k = 0; k < i; k++)
314 free(imageSet->scale[k]->imgBW);
316 for (k = 0; k < imageSet->num; k++) free(imageSet->scale[k]);
319 if (fread(&(imageSet->scale[i]->dpi),
sizeof(imageSet->scale[i]->dpi), 1, fp) != 1)
321 for (k = 0; k < i; k++)
323 free(imageSet->scale[k]->imgBW);
325 for (k = 0; k < imageSet->num; k++) free(imageSet->scale[k]);
329 arMalloc(imageSet->scale[i]->imgBW, ARUint8, imageSet->scale[i]->xsize * imageSet->scale[i]->ysize);
331 if (fread(imageSet->scale[i]->imgBW,
sizeof(ARUint8), imageSet->scale[i]->xsize * imageSet->scale[i]->ysize, fp)
332 != imageSet->scale[i]->xsize * imageSet->scale[i]->ysize)
334 for (k = 0; k <= i; k++)
336 free(imageSet->scale[k]->imgBW);
338 for (k = 0; k < imageSet->num; k++) free(imageSet->scale[k]);
347 free(imageSet->scale);
354AR2FeatureSetT* NFTDataLoader::ReadFeatureSet(boost::filesystem::path path)
356 AR2FeatureSetT *featureSet = NULL;
360 path.replace_extension(
".fset");
361 if ((fp = fopen(path.generic_string().c_str(),
"rb")) == NULL)
366 arMalloc(featureSet, AR2FeatureSetT, 1);
367 if (fread(&(featureSet->num),
sizeof(featureSet->num), 1, fp) != 1)
372 arMalloc(featureSet->list, AR2FeaturePointsT, featureSet->num);
373 for (i = 0; i < featureSet->num; i++)
375 if (fread(&(featureSet->list[i].scale),
sizeof(featureSet->list[i].scale), 1, fp) != 1)
379 if (fread(&(featureSet->list[i].maxdpi),
sizeof(featureSet->list[i].maxdpi), 1, fp) != 1)
383 if (fread(&(featureSet->list[i].mindpi),
sizeof(featureSet->list[i].mindpi), 1, fp) != 1)
387 if (fread(&(featureSet->list[i].num),
sizeof(featureSet->list[i].num), 1, fp) != 1)
392 arMalloc(featureSet->list[i].coord, AR2FeatureCoordT, featureSet->list[i].num);
393 for (j = 0; j < featureSet->list[i].num; j++)
395 if (fread(&(featureSet->list[i].coord[j].x),
sizeof(featureSet->list[i].coord[j].x), 1, fp) != 1)
399 if (fread(&(featureSet->list[i].coord[j].y),
sizeof(featureSet->list[i].coord[j].y), 1, fp) != 1)
403 if (fread(&(featureSet->list[i].coord[j].mx),
sizeof(featureSet->list[i].coord[j].mx), 1, fp) != 1)
407 if (fread(&(featureSet->list[i].coord[j].my),
sizeof(featureSet->list[i].coord[j].my), 1, fp) != 1)
411 if (fread(&(featureSet->list[i].coord[j].maxSim),
sizeof(featureSet->list[i].coord[j].maxSim), 1, fp) != 1)
421 for (l3 = 0; l3 < i; l3++) {
422 free(featureSet->list[l3].coord);
424 free(featureSet->list);
434AR2ImageT* NFTDataLoader::GetImageLayer(AR2ImageT* src,
float dpi)
440 int ii, jj, iii, jjj;
443 wx = (int)lroundf(src->xsize * dpi / src->dpi);
444 wy = (int)lroundf(src->ysize * dpi / src->dpi);
446 arMalloc(dst, AR2ImageT, 1);
450 arMalloc(dst->imgBW, ARUint8, wx*wy);
453 for (jj = 0; jj < wy; jj++)
455 sy = (int)lroundf(jj * src->dpi / dpi);
456 ey = (int)lroundf((jj + 1) * src->dpi / dpi) - 1;
457 if (ey >= src->ysize) ey = src->ysize - 1;
458 for (ii = 0; ii < wx; ii++)
460 sx = (int)lroundf(ii * src->dpi / dpi);
461 ex = (int)lroundf((ii + 1) * src->dpi / dpi) - 1;
462 if (ex >= src->xsize) ex = src->xsize - 1;
465 for (jjj = sy; jjj <= ey; jjj++)
467 p1 = &(src->imgBW[jjj*src->xsize + sx]);
468 for (iii = sx; iii <= ex; iii++)
474 *(p2++) = (co == 0) ? 0 : value / co;
492 m_maxFeatures = maxFeatures;
496 boost::filesystem::path bpath = filePath;
497 if (bpath.extension() ==
".fset" || bpath.extension() ==
".fset3")
499 bpath.replace_extension(
"");
504 if (nftLoader.
LoadData(bpath, &m_refDataSet, &m_surfaceSet) && m_refDataSet && m_surfaceSet)
506 m_imageSize.width = m_refDataSet->pageInfo[0].imageInfo[0].width;
507 m_imageSize.height = m_refDataSet->pageInfo[0].imageInfo[0].height;
509 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
510 m_pcorners.push_back(cv::Point2f(
static_cast<float>(m_imageSize.width), 0.0f));
511 m_pcorners.push_back(cv::Point2f(
static_cast<float>(m_imageSize.width),
static_cast<float>(m_imageSize.height)));
512 m_pcorners.push_back(cv::Point2f(0.0f,
static_cast<float>(m_imageSize.height)));
523 FILE* pFile = fopen(m_file.c_str(),
"rb");
527 fseek(pFile, 0, SEEK_END);
528 lSize = ftell(pFile);
532 buff = (
char*)malloc(lSize);
536 fread(buff, 1, lSize, pFile);
537 std::vector<char> data(buff, buff + lSize);
542 m_image = cv::imdecode(data, cv::IMREAD_GRAYSCALE);
546 MMechostr(MSKDEBUG,
">>>>> Picture not loaded ko\n");
548 MMechostr(MSKDEBUG,
">>>>> Picture loaded ok\n");
552 MMechostr(MSKDEBUG,
">>>>> Picture failed to open : %s\n", filePath.c_str());
555 m_image = cv::imread(m_file, cv::IMREAD_GRAYSCALE);
574 m_maxFeatures = maxFeatures;
576 cv::cvtColor(tpl,
m_image, cv::COLOR_RGB2GRAY);
588 m_cancelTrainning =
true;
589 if (m_trainingThread.joinable())
590 m_trainingThread.join();
593 m_cancelTrainning =
false;
609 nsize.width = (int)(((
float)
m_image.cols * (
float)msize) / (float)
m_image.rows);
610 nsize.height = msize;
615 nsize.height = (int)(((
float)
m_image.rows * (float)msize) / (float)
m_image.cols);
621 m_imageSize.width =
m_image.cols;
622 m_imageSize.height =
m_image.rows;
625 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
626 m_pcorners.push_back(cv::Point2f(
static_cast<float>(m_imageSize.width), 0.0f));
627 m_pcorners.push_back(cv::Point2f(
static_cast<float>(m_imageSize.width),
static_cast<float>(m_imageSize.height)));
628 m_pcorners.push_back(cv::Point2f(0.0f,
static_cast<float>(m_imageSize.height)));
629 m_trainingThread = boost::thread(&ArTkMarker::initTrackingPicture,
this);
636void ArTkMarker::CommonConstructor()
638 mNumGoodTracking = 0;
641 m_ftmi = arFilterTransMatInit(30.0, 28.0);
643 m_ftmi = arFilterTransMatInit(30.0, 20.0);
645 m_registerNextFrame =
false;
647 m_cancelTrainning =
false;
658 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
659 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
660 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
661 m_pcorners.push_back(cv::Point2f(0.0f, 0.0f));
676 m_cancelTrainning =
true;
677 if (m_trainingThread.joinable())
678 m_trainingThread.join();
680 std::vector<int> empty(2);
681 empty[0] = 0; empty[1] = 0;
686 kpmDeleteRefDataSet(&m_refDataSet);
689 ar2FreeSurfaceSet(&m_surfaceSet);
692 arFilterTransMatFinal(m_ftmi);
702 boost::system::error_code ec;
703 boost::filesystem::path bpath = path;
704 bpath.replace_extension(
".fset");
705 if (boost::filesystem::exists(bpath))
706 boost::filesystem::remove(bpath, ec);
708 bpath.replace_extension(
".fset3");
709 if (boost::filesystem::exists(bpath))
710 boost::filesystem::remove(bpath, ec);
712 bpath.replace_extension(
".iset");
713 if (boost::filesystem::exists(bpath))
714 boost::filesystem::remove(bpath, ec);
716 bpath.replace_extension(
"");
718 if (m_surfaceSet && m_surfaceSet->surface[0].imageSet)
719 ar2WriteImageSet((
char*)bpath.generic_string().c_str(), m_surfaceSet->surface[0].imageSet);
724 ar2SaveFeatureSet((
char*)bpath.generic_string().c_str(),
"fset", m_featureSet);
729 kpmSaveRefDataSet(bpath.generic_string().c_str(),
"fset3", m_refDataSet);
736bool ArTkMarker::LoadData(std::string filename)
746 boost::unique_lock<boost::recursive_mutex> l(m_trainningMutex);
748 KpmRefDataSet* refDataSet = NULL;
749 arMalloc(refDataSet, KpmRefDataSet, 1);
751 refDataSet->pageNum = 1;
752 refDataSet->num = m_refDataSet->num;
753 arMalloc(refDataSet->pageInfo, KpmPageInfo, 1);
754 arMalloc(refDataSet->refPoint, KpmRefData, refDataSet->num);
756 refDataSet->pageInfo[0].pageNo = m_refDataSet->pageInfo[0].pageNo;
757 refDataSet->pageInfo[0].imageNum = m_refDataSet->pageInfo[0].imageNum;
758 arMalloc(refDataSet->pageInfo[0].imageInfo, KpmImageInfo, m_refDataSet->pageInfo[0].imageNum);
760 for (
int i = 0; i < refDataSet->pageInfo[0].imageNum; i++)
762 refDataSet->pageInfo[0].imageInfo[i].imageNo = m_refDataSet->pageInfo[0].imageInfo[i].imageNo;
763 refDataSet->pageInfo[0].imageInfo[i].height = m_refDataSet->pageInfo[0].imageInfo[i].height;
764 refDataSet->pageInfo[0].imageInfo[i].width = m_refDataSet->pageInfo[0].imageInfo[i].width;
767 for (
int i = 0; i < refDataSet->num; i++)
769 refDataSet->refPoint[i].coord2D.x = m_refDataSet->refPoint[i].coord2D.x;
770 refDataSet->refPoint[i].coord2D.y = m_refDataSet->refPoint[i].coord2D.y;
771 refDataSet->refPoint[i].coord3D.x = m_refDataSet->refPoint[i].coord3D.x;
772 refDataSet->refPoint[i].coord3D.y = m_refDataSet->refPoint[i].coord3D.y;
773 refDataSet->refPoint[i].featureVec = m_refDataSet->refPoint[i].featureVec;
774 refDataSet->refPoint[i].pageNo = m_refDataSet->refPoint[i].pageNo;
775 refDataSet->refPoint[i].refImageNo = m_refDataSet->refPoint[i].refImageNo;
788 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
794 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
798void ArTkMarker::SetTracked(
bool state)
800 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
804void ArTkMarker::SetTrainned(
bool state)
806 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
812 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
818 boost::unique_lock<boost::recursive_mutex> l(m_dataMutex);
822bool ArTkMarker::initTrackingPicture()
824 boost::unique_lock<boost::recursive_mutex> l(m_trainningMutex);
828 kpmDeleteRefDataSet(&m_refDataSet);
834 ar2FreeSurfaceSet(&m_surfaceSet);
841 float dpiMax = std::max(m_imageSize.width, m_imageSize.height) / 3.93701f;
842 float dpiMin = truncf((28.0f / (
float)(std::min(m_imageSize.width, m_imageSize.height))) * dpiMax * 1000.0f) / 1000.0f;
843 float dpiWork = 0.0f;
847 if (dpiMin == dpiMax)
857 if (dpiWork <= dpiMin*0.95f)
867 dpi_num = std::min(dpi_num, 6);
868 else if (std::max(m_imageSize.width, m_imageSize.height) >= 800)
869 dpi_num = std::min(dpi_num, 16);
870 else if (std::max(m_imageSize.width, m_imageSize.height) >= 1024)
871 dpi_num = std::min(dpi_num, 8);
874 arMalloc(dpi_list,
float, dpi_num);
877 for (i = 0; i < dpi_num; i++)
879 dpi_list[i] = dpiWork;
882 if (dpiWork <= dpiMin*0.95f)
887 if (m_cancelTrainning)
890 AR2ImageSetT *imageSet = ar2GenImageSet(
m_image.data,
m_image.cols,
m_image.rows, 1, dpiMax, dpi_list, dpi_num);
895 AR2FeatureMapT *featureMap = NULL;
897 arMalloc(m_featureSet, AR2FeatureSetT, 1);
898 arMalloc(m_featureSet->list, AR2FeaturePointsT, imageSet->num);
900 m_featureSet->num = imageSet->num;
907 for (i = 0; i < imageSet->num; i++)
910 if (m_cancelTrainning)
913 featureMap = ar2GenFeatureMap(imageSet->scale[i],
914 AR2_DEFAULT_TS1*AR2_TEMP_SCALE, AR2_DEFAULT_TS2*AR2_TEMP_SCALE,
915 AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE1, AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE2,
916 AR2_DEFAULT_MAX_SIM_THRESH2, AR2_DEFAULT_SD_THRESH2);
918 if (featureMap == NULL)
920 ar2FreeImageSet(&imageSet);
921 ar2FreeFeatureSet(&m_featureSet);
930 if (m_cancelTrainning)
933 m_featureSet->list[i].coord = ar2SelectFeature2(imageSet->scale[i], featureMap,
934 AR2_DEFAULT_TS1*AR2_TEMP_SCALE, AR2_DEFAULT_TS2*AR2_TEMP_SCALE, AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE2,
935 AR2_DEFAULT_OCCUPANCY_SIZE * 2 / 3,
936 AR2_DEFAULT_MAX_SIM_THRESH_L3, AR2_DEFAULT_MIN_SIM_THRESH_L3, AR2_DEFAULT_SD_THRESH_L3, &numFeatures);
938 if (m_featureSet->list[i].coord == NULL)
941 m_featureSet->list[i].num = numFeatures;
942 m_featureSet->list[i].scale = i;
945 for (j = 0; j < imageSet->num; j++)
947 if (imageSet->scale[j]->dpi < imageSet->scale[i]->dpi)
949 if (imageSet->scale[j]->dpi > scale1)
950 scale1 = imageSet->scale[j]->dpi;
956 m_featureSet->list[i].mindpi = imageSet->scale[i]->dpi * 0.5f;
960 m_featureSet->list[i].mindpi = scale1;
964 for (j = 0; j < imageSet->num; j++)
966 if (imageSet->scale[j]->dpi > imageSet->scale[i]->dpi)
968 if (scale1 == 0.0f || imageSet->scale[j]->dpi < scale1)
969 scale1 = imageSet->scale[j]->dpi;
975 m_featureSet->list[i].maxdpi = imageSet->scale[i]->dpi * 2.0f;
979 scale2 = imageSet->scale[i]->dpi;
980 m_featureSet->list[i].maxdpi = scale2*0.8f + scale1*0.2f;
983 ar2FreeFeatureMap(featureMap);
987 if (m_cancelTrainning)
991 arMalloc(m_surfaceSet, AR2SurfaceSetT, 1);
992 m_surfaceSet->num = 1;
993 m_surfaceSet->contNum = 0;
994 arMalloc(m_surfaceSet->surface, AR2SurfaceT, m_surfaceSet->num);
995 m_surfaceSet->surface[0].imageSet = imageSet;
996 m_surfaceSet->surface[0].featureSet = m_featureSet;
997 m_surfaceSet->surface[0].markerSet = NULL;
998 m_surfaceSet->surface[0].jpegName = NULL;
1000 for (j = 0; j < 3; j++)
1002 for (k = 0; k < 4; k++)
1004 m_surfaceSet->surface[0].trans[j][k] = (j == k) ? 1.0f : 0.0f;
1008 arUtilMatInvf((
const float(*)[4])m_surfaceSet->surface[0].trans, m_surfaceSet->surface[0].itrans);
1010 int procMode = KpmProcFullSize;
1012 int featureDensity = m_maxFeatures;
1014 for (i = 0; i < imageSet->num; i++)
1017 if (m_cancelTrainning)
1020 maxFeatureNum = featureDensity * imageSet->scale[i]->xsize * imageSet->scale[i]->ysize / (480 * 360);
1022 if (!maxFeatureNum || kpmAddRefDataSet(imageSet->scale[i]->imgBW, imageSet->scale[i]->xsize, imageSet->scale[i]->ysize,
1023 imageSet->scale[i]->dpi,
1024 procMode, KpmCompNull, maxFeatureNum, 1, i, &m_refDataSet) < 0)
1027 kpmDeleteRefDataSet(&m_refDataSet);
1029 ar2FreeSurfaceSet(&m_surfaceSet);
1055 m_registerNextFrame =
true;
1060 boost::unique_lock<boost::recursive_mutex> l(m_mutex);
1061 m_warped.copyTo(image);
1069void ArTkMarker::WarpMarkerImage(cv::Mat color)
1071 cv::Mat HMatrix = cv::findHomography(m_pcorners, *
this);
1073 boost::unique_lock<boost::recursive_mutex> l(m_mutex);
1074 cv::warpPerspective(color, m_warped, HMatrix, cv::Size(m_imageSize.width, m_imageSize.height), cv::WARP_INVERSE_MAP | cv::INTER_CUBIC);
1077void ArTkMarker::ComputeMatrix(
ArCameraParam &camParams,
bool reverse)
1079 float halfSizeX = 0.0f;
1080 float halfSizeY = 0.0f;
1081 if (m_imageSize.height >= m_imageSize.width)
1083 halfSizeY =
m_size / 2.0f;
1084 halfSizeX = ((m_imageSize.width *
m_size) / m_imageSize.height) / 2.0f;
1088 halfSizeY = ((m_imageSize.height *
m_size) / m_imageSize.width) / 2.0f;
1089 halfSizeX =
m_size / 2.0f;
1106 arFilterTransMat(m_ftmi, mTackingPos,
false);
1108 double modelview_matrix[16];
1111 cv::Mat R(4, 4, CV_32F);
1112 R.at<
float>(0, 0) = mTackingPos[0][0];
1113 R.at<
float>(0, 1) = mTackingPos[0][1];
1114 R.at<
float>(0, 2) = mTackingPos[0][2];
1115 R.at<
float>(0, 3) = mTackingPos[0][3];
1116 R.at<
float>(1, 0) = mTackingPos[1][0];
1117 R.at<
float>(1, 1) = mTackingPos[1][1];
1118 R.at<
float>(1, 2) = mTackingPos[1][2];
1119 R.at<
float>(1, 3) = mTackingPos[1][3];
1120 R.at<
float>(2, 0) = mTackingPos[2][0];
1121 R.at<
float>(2, 1) = mTackingPos[2][1];
1122 R.at<
float>(2, 2) = mTackingPos[2][2];
1123 R.at<
float>(2, 3) = mTackingPos[2][3];
1126 cv::Mat RX = cv::Mat::eye(4, 4, CV_32F);
1127 float angleRad = M_PI / 2;
1128 RX.at<
float>(1, 1) = cos(angleRad);
1129 RX.at<
float>(1, 2) = -sin(angleRad);
1130 RX.at<
float>(2, 1) = sin(angleRad);
1131 RX.at<
float>(2, 2) = cos(angleRad);
1136 modelview_matrix[0 + 0 * 4] = R.at<
float>(0, 0);
1137 modelview_matrix[0 + 1 * 4] = R.at<
float>(0, 1);
1138 modelview_matrix[0 + 2 * 4] = R.at<
float>(0, 2);
1139 modelview_matrix[0 + 3 * 4] = R.at<
float>(0, 3);
1140 modelview_matrix[1 + 0 * 4] = R.at<
float>(1, 0);
1141 modelview_matrix[1 + 1 * 4] = R.at<
float>(1, 1);
1142 modelview_matrix[1 + 2 * 4] = R.at<
float>(1, 2);
1143 modelview_matrix[1 + 3 * 4] = R.at<
float>(1, 3);
1144 modelview_matrix[2 + 0 * 4] = -R.at<
float>(2, 0);
1145 modelview_matrix[2 + 1 * 4] = -R.at<
float>(2, 1);
1146 modelview_matrix[2 + 2 * 4] = -R.at<
float>(2, 2);
1147 modelview_matrix[2 + 3 * 4] = -R.at<
float>(2, 3);
1148 modelview_matrix[3 + 0 * 4] = 0.0;
1149 modelview_matrix[3 + 1 * 4] = 0.0;
1150 modelview_matrix[3 + 2 * 4] = 0.0;
1151 modelview_matrix[3 + 3 * 4] = 1.0;
1156 double f =
m_size * 0.01;
1157 modelview_matrix[12] *= f;
1158 modelview_matrix[13] *= f;
1159 modelview_matrix[14] *= f;
1162 cv::Point3d p(halfSizeX, 0.0, -halfSizeY);
1163 cv::Matx33d Rt = cv::Matx33d::eye();
1165 Rt(0, 0) = modelview_matrix[0 + 0 * 4];
1166 Rt(0, 1) = modelview_matrix[0 + 1 * 4];
1167 Rt(0, 2) = modelview_matrix[0 + 2 * 4];
1168 Rt(1, 0) = modelview_matrix[1 + 0 * 4];
1169 Rt(1, 1) = modelview_matrix[1 + 1 * 4];
1170 Rt(1, 2) = modelview_matrix[1 + 2 * 4];
1171 Rt(2, 0) = modelview_matrix[2 + 0 * 4];
1172 Rt(2, 1) = modelview_matrix[2 + 1 * 4];
1173 Rt(2, 2) = modelview_matrix[2 + 2 * 4];
1175 cv::Point3d roff = Rt * p;
1176 modelview_matrix[12] += roff.x;
1177 modelview_matrix[13] += roff.y;
1178 modelview_matrix[14] += roff.z;
1180 cv::Mat rot(3, 3, CV_32FC1);
1181 rot.at<
float>(0, 0) = mTackingPos[0][0];
1182 rot.at<
float>(0, 1) = mTackingPos[0][1];
1183 rot.at<
float>(0, 2) = mTackingPos[0][2];
1184 rot.at<
float>(1, 0) = mTackingPos[1][0];
1185 rot.at<
float>(1, 1) = mTackingPos[1][1];
1186 rot.at<
float>(1, 2) = mTackingPos[1][2];
1187 rot.at<
float>(2, 0) = mTackingPos[2][0];
1188 rot.at<
float>(2, 1) = mTackingPos[2][1];
1189 rot.at<
float>(2, 2) = mTackingPos[2][2];
1191 cv::Rodrigues(rot, Rvec);
1193 Tvec.at<
float>(0, 0) = modelview_matrix[12];
1194 Tvec.at<
float>(1, 0) = modelview_matrix[13];
1195 Tvec.at<
float>(2, 0) = -modelview_matrix[14];
1198 std::vector<cv::Point3d> corner3d;
1199 corner3d.push_back(cv::Point3d(-halfSizeX, halfSizeY, 0.0));
1200 corner3d.push_back(cv::Point3d(halfSizeX, halfSizeY, 0.0));
1201 corner3d.push_back(cv::Point3d(halfSizeX, -halfSizeY, 0.0));
1202 corner3d.push_back(cv::Point3d(-halfSizeX, -halfSizeY, 0.0));
1204 std::vector<cv::Point2d> projectedPoints;
1205 cv::projectPoints(corner3d, Rvec, Tvec, camParams.
camParam.CameraMatrix, camParams.
camParam.Distorsion, projectedPoints);
1207 for (
int j = 0; j < projectedPoints.size(); j++)
1209 (*this).at(j).x = (float)projectedPoints[j].x;
1210 (*this).at(j).y = (float)projectedPoints[j].y;
1214 Vector3 pixelPosition(0.0, 0.0, 0.0);
1215 for (
int j = 0; j < 4; j++)
1217 pixelPosition.x += (*this).at(j).x;
1218 pixelPosition.y += (*this).at(j).y;
1221 pixelPosition.z = sqrt(pow(((*this).at(1).x - (*this).at(0).x), 2) + pow(((*this).at(1).y - (*this).at(0).y), 2));
1222 pixelPosition.z += sqrt(pow(((*this).at(2).x - (*this).at(1).x), 2) + pow(((*this).at(2).y - (*this).at(1).y), 2));
1223 pixelPosition.z += sqrt(pow(((*this).at(3).x - (*this).at(2).x), 2) + pow(((*this).at(3).y - (*this).at(2).y), 2));
1224 pixelPosition.z += sqrt(pow(((*this).at(0).x - (*this).at(3).x), 2) + pow(((*this).at(0).y - (*this).at(3).y), 2));
1226 pixelPosition.x /= 4.;
1227 pixelPosition.y /= 4.;
1228 pixelPosition.z /= 4.;
1234 SetPosition(
Vector3(
static_cast<float>(reverse ? -modelview_matrix[12] : modelview_matrix[12]) + offset.x, static_cast<float>(modelview_matrix[13]) + offset.y, static_cast<float>(modelview_matrix[14]) + offset.z));
1240 std::vector<double> filterVals;
1242 for (j = 0; j < 3; j++)
1243 for (i = 0; i < 4; i++)
1245 mCamPose[j][i] = camPose[j][i];
1246 mTackingPos[j][i] = camPose[j][i];
1250 mNumGoodTracking = 0;
1251 ar2SetInitTrans(m_surfaceSet, mCamPose);
1254 arFilterTransMat(m_ftmi, mTackingPos,
true);
1255 ComputeMatrix(camParams, reverse);
1256 WarpMarkerImage(color);
1258 if (
IsTrained() && m_trainingThread.joinable())
1259 m_trainingThread.join();
1265 if (m_registerNextFrame && camsize.width != 0 && camsize.height != 0 && m_cropSize.width > 1 && m_cropSize.height > 1)
1267 m_registerNextFrame =
false;
1269 cv::Point2f scale = cv::Point2f((
float)frame.cols / (
float)camsize.width, (
float)frame.rows / (
float)camsize.height);
1271 m_cropPos.x = (int)((
float)m_cropPos.x * tscale * scale.x);
1272 m_cropPos.y = (int)((
float)m_cropPos.y * tscale * scale.y);
1273 m_cropSize.width = (int)((
float)m_cropSize.width * tscale * scale.x);
1274 m_cropSize.height = (int)((
float)m_cropSize.height * tscale * scale.x);
1278 cv::Mat crop(frame, cv::Rect(m_cropPos.x, m_cropPos.y, m_cropSize.width, m_cropSize.height));
1282 if (crop.rows >= crop.cols)
1284 nsize.width = (int)(((
float)crop.cols * (
float)msize) / (float)crop.rows);
1285 nsize.height = msize;
1289 nsize.width = msize;
1290 nsize.height = (int)(((
float)crop.rows * (float)msize) / (float)crop.cols);
1293 cv::resize(crop, crop, nsize, 0, 0, cv::INTER_CUBIC);
1297 catch (std::exception &)
1300 MMechostr(MSKDEBUG,
"detectNFT : failed to set the current frame as marker.\n");
1314 if (ar2Tracking(ar2handle, m_surfaceSet, frame.data, mCamPose, &err) < 0)
1324 for (j = 0; j < 3; j++)
1325 for (i = 0; i < 4; i++)
1327 mTackingPos[j][i] = mCamPose[j][i];
1331 ComputeMatrix(camParams, reverse);
1335 if (mNumGoodTracking < 4)
int AR_MARKER_TRAINNED_CB
#define MIN_TRACKED_MARKER_SIZE
Vector3 GetCameraOffset()
aruco::CameraParameters camParam
void SetNFTdetectorDirty()
static ArManager * GetInstance()
void SetPixelPosition(Vector3 pixelpos)
void SetPosition(Vector3 pos)
void SetOrientation(BtQuaternion orientation)
void SetVisible(bool visible)
void SetPageNum(int page)
bool GetWarpedMarker(cv::Mat &image)
bool TrackFrame(AR2HandleT *ar2handle, const cv::Mat &color, const cv::Mat &frame, ArCameraParam &camParams, const bool &reverse)
bool SaveData(std::string path)
ArTkMarker(std::string filePath, unsigned int nid, float size, unsigned int maxFeatures=600)
bool RegisterCurrentFrame(const cv::Mat &frame, cv::Size camsize, float tscale=1.0f)
void RegisterNextFrame(cv::Point point, cv::Size size)
void StartTracking(cv::Mat color, const float camPose[3][4], ArCameraParam &camParams, const bool &reverse)
KpmRefDataSet * GetDataSet()
void SetTrackedImage(cv::Mat tpl)
static BtQuaternion FromRotationMatrix(double rotMatrix[16], bool reverseX=false, bool reverseY=true)
bool LoadData(boost::filesystem::path path, KpmRefDataSet **refDataSetPtr, AR2SurfaceSetT **surfaceSetPtr)