Перейти к содержимому
Compvision.ru

ELGEON

Пользователи
  • Количество публикаций

    28
  • Зарегистрирован

  • Посещение

  • Days Won

    1

ELGEON last won the day on May 8 2012

ELGEON had the most liked content!

Репутация

2 Новичек

О ELGEON

  • Звание
    Бывалый
  1. Проблемы с ExtractSURF() и CvMemStorage

    Нашел одну статью: K-d дерево строится по следующему правилу: • начальное множество разбивается по значениям векторов в одной из координат, например, по i = 1,…k, на два подмножества; • i выбирается таким образом, чтобы разброс значений по данной координате был максимальным; • разбиение проводится по медиане m, так что одинаковое количество точек оказывается с одной и с другой стороны; • в вершине дерева хранятся значения i , m, разброс значений векторов по каждой координате; • для полученных вершин процесс повторяется. Для поиска n ближайших соседей к вектору q в построенном дереве: • сначала дерево обходится вниз до листа содержащего «ближайшую» к q точку. Эта точка не обязана быть ближайшей, это только первое приближение; • во время спуска по дереву заполняется список поддеревьев, которые еще не обходили. Также запоминаются расстояния до них, которое определяется как минимальное расстояние от точки q до любой точки, находящейся в границах значений поддерева; • из списка выбираем ближайшее к q поддерево и продолжаем поиск в нём; • расстояние до каждого нового найденного претендента сравнивается с радиусом сферы найденных точек с центром в точке q. Если данное расстояние меньше, то точку на сфере заменяем этим претендентом. Алгоритм работает до тех пор, пока в списке есть поддеревья с расстоянием, меньшим радиуса сферы найденных точек.
  2. Проблемы с ExtractSURF() и CvMemStorage

    Спасибо =) Начал читать, затянуло =)
  3. Проблемы с ExtractSURF() и CvMemStorage

    Мне KD пришлось заменить на cvCreateFeatureTree. Просто не нашел нормального объяснения данного алгоритма на русском Можно чуть поподробнее, если не затруднит? Такой способ как-то называется?
  4. Проблемы с ExtractSURF() и CvMemStorage

    Объясните пожалуйста как работает этот блок и что это заметод? CvFeatureTree* tr = cvCreateFeatureTree(desc1mat); CvMat *matches = cvCreateMat(kp2->total,1,CV_32SC1); CvMat *distances = cvCreateMat(kp2->total,1,CV_64FC1); cvFindFeatures(tr, desc2mat, matches, distances, 1, 250); cvReleaseFeatureTree(tr); // int *reverseLookup = (int*)malloc(sizeof(int)*kp1->total); // double *reverseLookupDist = (double*)malloc(sizeof(double)*kp1->total); // for (int i = 0; i < kp1->total; ++i) { reverseLookup[i] = -1; reverseLookupDist[i] = DBL_MAX; } int matchCount = 0; for (int j = 0; j < kp2->total; ++j) { int i = (int)cvGetReal2D(matches, j, 0); double d = (double)cvGetReal2D(distances, j, 0); if (d < reverseLookupDist[i]) { if (reverseLookupDist[i] == DBL_MAX) matchCount++; reverseLookup[i] = j; reverseLookupDist[i] = d; } } points1 = cvCreateMat(1,matchCount,CV_32FC2); points2 = cvCreateMat(1,matchCount,CV_32FC2); CvPoint2D32f *p1, *p2; int m = 0; for (int j = 0; j < kp2->total; j++) { int i = (int)cvGetReal2D(matches, j, 0); if (j == reverseLookup[i]) { p1 = &((CvSURFPoint*)cvGetSeqElem(kp1,i))->pt; p2 = &((CvSURFPoint*)cvGetSeqElem(kp2,j))->pt; points1->data.fl[m*2] = p1->x; points1->data.fl[m*2+1] = p1->y; points2->data.fl[m*2] = p2->x; points2->data.fl[m*2+1] = p2->y; m++; } } free(reverseLookup); free(reverseLookupDist);
  5. Надеялся что будет простое решение =( Дело в том что не могу произвести такое количество действий. Думал что могут как-то помочь cvRemap или cvWarpAffine. Может какой-то недочет в коде? Нашел сайт по скриншотам вроде оно: http://blog.naver.com/PostView.nhn?blogId=tramper2&logNo=100086964864&categoryNo=20&viewDate=&currentPage=1&listtype=0 Почти как описали
  6. Код приложения (нашел на каком-то сайте), пытаюсь реализовать под свои нужды: // StartOpenCV.cpp: определяет точку входа для консольного приложения. // /** #include "stdafx.h" #include <cv.h> int _tmain(int argc, _TCHAR* argv[]) { return 0; } */ #include "StdAfx.h" #include <iostream> #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <cvaux.h> using namespace std; typedef struct MATCH_PAIR { int nA; int nB; } MATCH_PAIR; void MergeImages(IplImage* Image1, IplImage* Image2, IplImage* dstImage); int FindMatchingPoints(const CvSeq* tKeypoints, const CvSeq* tDescriptors, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size, MATCH_PAIR *pMatchPair); int FindNearestPoints(const float* pA, int laplacian, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size); //void main() //{ int _tmain(int argc, _TCHAR* argv[]) { IplImage *T1Img = cvLoadImage("C:/im2.jpg"); IplImage *T2Img = cvLoadImage("C:/im1.jpg"); IplImage *mT2Img, *mT1Img; mT1Img = cvCreateImage(cvSize(T1Img->width, T1Img->height),T1Img->depth, 1); cvCvtColor(T1Img, mT1Img, CV_BGR2GRAY); mT2Img = cvCreateImage(cvSize(T2Img->width, T2Img->height),T2Img->depth, 1); cvCvtColor(T2Img, mT2Img, CV_BGR2GRAY); CvMemStorage* storage =cvCreateMemStorage(0); CvSURFParams params = cvSURFParams(1000, 0); CvSeq *T1_Keypoints = NULL; CvSeq *T1_Descriptors = NULL; cvExtractSURF(mT1Img, NULL, &T1_Keypoints, &T1_Descriptors, storage, params); CvSeq *T2_Keypoints = NULL; CvSeq *T2_Descriptors = NULL; cvExtractSURF(mT2Img, NULL, &T2_Keypoints, &T2_Descriptors, storage, params); CvSURFPoint* surf1; CvSURFPoint* surf2; MATCH_PAIR *pMatchPair = new MATCH_PAIR[T1_Keypoints->total]; int descriptor_size = params.extended? 128 : 64; int nMatchingCount = FindMatchingPoints(T1_Keypoints, T1_Descriptors, T2_Keypoints, T2_Descriptors, descriptor_size, pMatchPair); CvPoint2D32f *pt1 = new CvPoint2D32f[nMatchingCount]; CvPoint2D32f *pt2 = new CvPoint2D32f[nMatchingCount]; int x1, y1, x2, y2; for(int k=0; k<nMatchingCount; k++) { surf1 = (CvSURFPoint*) cvGetSeqElem(T1_Keypoints, pMatchPair[k].nA); x1 = cvRound(surf1->pt.x); y1 = cvRound(surf1->pt.y); surf2 = (CvSURFPoint*) cvGetSeqElem(T2_Keypoints, pMatchPair[k].nB); x2 = cvRound(surf2->pt.x) + T1Img->width; y2 = cvRound(surf2->pt.y); CvPoint r1 = cvPoint(x1, y1); CvPoint r2 = cvPoint(x2, y2); pt1[k] = surf1->pt; pt2[k] = surf2->pt; } if(nMatchingCount<4) { return 0; } CvMat M1, M2; double H[9]; CvMat mxH = cvMat(3, 3, CV_64F, H); M1 = cvMat(1, nMatchingCount, CV_32FC2, pt1); M2 = cvMat(1, nMatchingCount, CV_32FC2, pt2); if( !cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2)) { return 0; } IplImage* WarpImg = cvCreateImage(cvSize(T1Img->width*2, T1Img->height*1.5), T1Img->depth, T1Img->nChannels); cvWarpPerspective(T1Img, WarpImg, &mxH); cvSetImageROI(WarpImg, cvRect(0, 0, T2Img->width, T2Img->height)); cvCopy(T2Img, WarpImg); cvResetImageROI(WarpImg); cvNamedWindow("WarpImg Img",1); cvShowImage("WarpImg Img", WarpImg); cvWaitKey(0); delete pMatchPair; delete pt1; delete pt2; cvReleaseImage(&WarpImg); cvReleaseImage(&T1Img); cvReleaseImage(&T2Img); cvReleaseImage(&mT1Img); cvReleaseImage(&mT2Img); } void MergeImages(IplImage* Image1, IplImage* Image2, IplImage* dstImage) { cvSet(dstImage, CV_RGB(255, 255, 255)); cvSetImageROI(dstImage, cvRect(0, 0, Image1->width, Image1->height)); cvSetImageCOI(dstImage, 1); //Г¤іО 1 cvCopy(Image1, dstImage); cvSetImageCOI(dstImage, 2); //Г¤іО 2 cvCopy(Image1, dstImage); cvSetImageCOI(dstImage, 3); //Г¤іО 3 cvCopy(Image1, dstImage); cvSetImageROI(dstImage, cvRect(Image1->width, 0, Image2->width, Image2->height)); cvSetImageCOI(dstImage, 1); //Г¤іО 1 cvCopy(Image2, dstImage); cvSetImageCOI(dstImage, 2); //Г¤іО 2 cvCopy(Image2, dstImage); cvSetImageCOI(dstImage, 3); //Г¤іО 3 cvCopy(Image2, dstImage); cvResetImageROI(dstImage); } int FindMatchingPoints(const CvSeq* tKeypoints, const CvSeq* tDescriptors, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size, MATCH_PAIR *pMatchPair) { int i; float* pA; int nMatchB; CvSURFPoint* surfA; int k=0; for(i=0; i<tDescriptors->total; i++) { pA = (float*) cvGetSeqElem(tDescriptors, i); surfA = (CvSURFPoint*) cvGetSeqElem(tKeypoints, i); nMatchB = FindNearestPoints(pA, surfA->laplacian, srcKeypoints, srcDescriptors, descriptor_size); if(nMatchB > 0) { pMatchPair[k].nA=i; pMatchPair[k].nB = nMatchB; k++; } } return k; } int FindNearestPoints(const float* pA, int laplacian, const CvSeq* srcKeypoints, const CvSeq* srcDescriptors, int descriptor_size) { int i, k; float* pB; CvSURFPoint *surfB; int nMatch = -1; double sum2, min1 = 1000, min2 = 1000; for(i=0; i<srcDescriptors->total; i++) { surfB = (CvSURFPoint*) cvGetSeqElem(srcKeypoints, i); pB = (float*) cvGetSeqElem(srcDescriptors, i); if(laplacian != surfB->laplacian) continue; sum2 = 0.0f; for(k=0; k<descriptor_size; k++) { sum2 +=(pA[k]-pB[k])*(pA[k]-pB[k]); } if(sum2 < min1) { min2 = min1; min1 = sum2; nMatch = i; } else if(sum2<min2) { min2 = sum2; } } if(min1<0.6*min2) return nMatch; return -1; }
  7. И сразу еще один вопрос задам: правое (преобразованное) изображение сильно потеряло в качестве, что при разрешении 600х450 очень заметно. Тут я уже ничего поделать не смогу?
  8. Ну как я понял самый простой вариант - это обрезать ту часть, которая выходит за границы прямоугольника. После cvWarpPerspective правую часть растянуло. Можно ли преобразовать изображение к прямоугольному виду, т.е. как-то выровнять?
  9. cvTransform может как-то в этом помочь?
  10. Как можно после склейки двух изображений результат "ужать" в прямоугольник? Может есть какая-нибудь функция в opencv или готовый алгоритм?
  11. OpenCV_Android_склейка

    Я знаю про этот модуль, но мне нужно реализовать без него
  12. OpenCV_Android_склейка

    Жаль реализации нету Может, как вариант, не правое изображение преобразовывать, а левое - правое вроде должно остаться исходным и по идее к нему можно лепить следующее. Хотя при добавлении следующей фотки правое исказится и связь с левым пропадет. Или нет?
  13. OpenCV_Android_склейка

    Тесты проги завели мобилу в циклический ребут, перепрошил и изображения начали нормально загружаться - просто чудо расчудесное У меня еще один вопрос: Когда я загружаю картинки и они склеиваются правое изображение (которое подгоняем) после преобразований немного размывается, искажается. Можно ли его как-то выравнивать? Мне просто к нему нужно еще одно изображение прилепить.
  14. OpenCV_Android_склейка

    Нашел разницу между изображениями, те что с компа имеют глубину цвета 32, а с телефона - 24 Это может как-то приводить к ошибке?
  15. OpenCV_Android_склейка

    Появилась проблема - не могу склеить снимки с камеры. Каждую фотку сохраняю в формате png, потом пытаюсь загрузить в Iplimage. Попробовал взять фотки с компа - склеились(тоже png). Не могу понять в чем проблема. Форматы одинаковые, но с телефонными фотками работать не хочет
×