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

ELGEON

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

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

  • Посещение

  • Days Won

    1

Все публикации пользователя ELGEON

  1. Всем привет! Очень прошу помочь в одном вопросе. Я пишу курсовую под android. Цель моей работы сделать 2 фотографии и склеить их. Фотографии программа делает, сохраняет и т.д. Когда пришло время склеивать изображения перерыл весь интернет в поисках теории и кода, узнал что многие активно пользуются OpenCV. Я смог импортировать библиотеки OpenCV в свой проект и всё, дальше ничего не могу сделать, так как совсем не имел дела с этими библиотеками. Нашел пару ссылок по этой теме, но не знаю можно ли использовать предоставленный там код 1 2 Помогите пожалуйста кодом или хотя бы советом, а то сижу уже 2 недели без продвижений
  2. Проблемы с ExtractSURF() и CvMemStorage

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

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

    Мне KD пришлось заменить на cvCreateFeatureTree. Просто не нашел нормального объяснения данного алгоритма на русском Можно чуть поподробнее, если не затруднит? Такой способ как-то называется?
  5. Проблемы с 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);
  6. Как можно после склейки двух изображений результат "ужать" в прямоугольник? Может есть какая-нибудь функция в opencv или готовый алгоритм?
  7. Надеялся что будет простое решение =( Дело в том что не могу произвести такое количество действий. Думал что могут как-то помочь cvRemap или cvWarpAffine. Может какой-то недочет в коде? Нашел сайт по скриншотам вроде оно: http://blog.naver.com/PostView.nhn?blogId=tramper2&logNo=100086964864&categoryNo=20&viewDate=&currentPage=1&listtype=0 Почти как описали
  8. Код приложения (нашел на каком-то сайте), пытаюсь реализовать под свои нужды: // 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; }
  9. И сразу еще один вопрос задам: правое (преобразованное) изображение сильно потеряло в качестве, что при разрешении 600х450 очень заметно. Тут я уже ничего поделать не смогу?
  10. Ну как я понял самый простой вариант - это обрезать ту часть, которая выходит за границы прямоугольника. После cvWarpPerspective правую часть растянуло. Можно ли преобразовать изображение к прямоугольному виду, т.е. как-то выровнять?
  11. cvTransform может как-то в этом помочь?
  12. OpenCV_Android_склейка

    Народ, очень срочно нужна помощь! Пытаюсь склеить 2 изображения, но прога на определенном моменте просто закрывается. В VS2010 все нормально склеивается. А в Android максимум могу вывести особые точки. Может есть ошибка, которую не заметил. Делаю в Eclipse. вот код: (OpenCV, C++) #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <cv.h> #include <cvaux.h> #include <highgui.h> #include <cxcore.h> #include "bmpfmt.h" typedef struct MATCH_PAIR { int nA; int nB; } MATCH_PAIR; extern "C"{ CvScalar colors[] = {{{0,0,255}},{{255,255,255}}}; IplImage* WarpImg = NULL; IplImage* pImage1 = NULL; IplImage* pImage2 = NULL; IplImage* loadPixels(int* pixels, int width, int height); IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data, jint width, jint height); 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); JNIEXPORT void JNICALL Java_com_first_cv_OCV_extractSURFFeature(JNIEnv* env, jobject thiz) { CvMemStorage* storage = cvCreateMemStorage(0); CvSURFParams params = cvSURFParams(1000, 0); IplImage *pWorkImage1 = cvCreateImage(cvGetSize(pImage1),IPL_DEPTH_8U,1); cvCvtColor(pImage1,pWorkImage1,CV_BGR2GRAY); CvSeq *imageKeypoints1 = 0, *imageDescriptors1 = 0; cvExtractSURF( pWorkImage1, 0, &imageKeypoints1, &imageDescriptors1, storage, params ); cvReleaseImage(&pWorkImage1); /** int i; CvSURFPoint *r; CvPoint center; for( int i = 0; i < imageKeypoints1->total; i++ ) { r = (CvSURFPoint*)cvGetSeqElem( imageKeypoints1, i ); center.x = cvRound(r->pt.x); center.y = cvRound(r->pt.y); cvCircle( pImage1, center, 1, CV_RGB(0,200,0), 1, CV_AA, 0 ); } */ IplImage *pWorkImage2 = cvCreateImage(cvGetSize(pImage2),IPL_DEPTH_8U,1); cvCvtColor(pImage2,pWorkImage2,CV_BGR2GRAY); CvSeq *imageKeypoints2 = 0, *imageDescriptors2 = 0; cvExtractSURF( pWorkImage2, 0, &imageKeypoints2, &imageDescriptors2, storage, params ); cvReleaseImage(&pWorkImage2); /** for( int i = 0; i < imageKeypoints2->total; i++ ) { r = (CvSURFPoint*)cvGetSeqElem( imageKeypoints2, i ); center.x = cvRound(r->pt.x); center.y = cvRound(r->pt.y); cvCircle( pImage2, center, 1, CV_RGB(0,200,0), 1, CV_AA, 0 ); } */ CvSURFPoint* surf1; CvSURFPoint* surf2; MATCH_PAIR *pMatchPair = new MATCH_PAIR[imageKeypoints1->total]; int descriptor_size = params.extended; int nMatchingCount = FindMatchingPoints(imageKeypoints1, imageDescriptors1, imageKeypoints2, imageDescriptors2, 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(imageKeypoints1, pMatchPair[k].nA); x1 = cvRound(surf1->pt.x); y1 = cvRound(surf1->pt.y); surf2 = (CvSURFPoint*) cvGetSeqElem(imageKeypoints2, pMatchPair[k].nB); x2 = cvRound(surf2->pt.x) + pImage1->width; y2 = cvRound(surf2->pt.y); CvPoint r1 = cvPoint(x1, y1); CvPoint r2 = cvPoint(x2, y2); pt1[k] = surf1->pt; pt2[k] = surf2->pt; } CvMat M1, M2; double H[9]; CvMat mxH = cvMat(3, 3, CV_32F, H); M1 = cvMat(1, nMatchingCount, CV_32FC2, pt1); M2 = cvMat(1, nMatchingCount, CV_32FC2, pt2); cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2); IplImage* WarpImg = cvCreateImage(cvSize(pImage1->width*2, pImage1->height*2), pImage1->depth, pImage1->nChannels); cvWarpPerspective(pImage1, WarpImg, &mxH); cvSetImageROI(WarpImg, cvRect(0, 0, pImage2->width, pImage2->height)); cvCopy(pImage2, WarpImg); cvResetImageROI(WarpImg); delete pMatchPair; delete pt1; delete pt2; cvReleaseMemStorage(&storage); cvReleaseImage(&pImage1); cvReleaseImage(&pImage2); } JNIEXPORT jboolean JNICALL Java_com_first_cv_OCV_setSourceImage(JNIEnv* env, jobject thiz, jintArray photo_data, jint width, jint height) { if (pImage1 != NULL) { cvReleaseImage(&pImage1); pImage1 = NULL; } pImage1 = getIplImageFromIntArray(env, photo_data, width, height); if (pImage1 == NULL) { return 0; } return 1; } JNIEXPORT jboolean JNICALL Java_com_first_cv_OCV_setSourceImageTwo(JNIEnv* env, jobject thiz, jintArray photo_datas, jint widths, jint heights) { if (pImage2 != NULL) { cvReleaseImage(&pImage2); pImage2 = NULL; } pImage2 = getIplImageFromIntArray(env, photo_datas, widths, heights); if (pImage2 == NULL) { return 0; } return 1; } JNIEXPORT jbooleanArray JNICALL Java_com_first_cv_OCV_getSourceImage(JNIEnv* env, jobject thiz) { if (WarpImg == NULL) { return 0; } cvFlip(WarpImg); int width = WarpImg->width; int height = WarpImg->height; int rowStep = WarpImg->widthStep; int headerSize = 54; int imageSize = rowStep * height; int fileSize = headerSize + imageSize; unsigned char* image = new unsigned char[fileSize]; struct bmpfile_header* fileHeader = (struct bmpfile_header*) (image); fileHeader->magic[0] = 'B'; fileHeader->magic[1] = 'M'; fileHeader->filesz = fileSize; fileHeader->creator1 = 0; fileHeader->creator2 = 0; fileHeader->bmp_offset = 54; struct bmp_dib_v3_header_t* imageHeader = (struct bmp_dib_v3_header_t*) (image + 14); imageHeader->header_sz = 40; imageHeader->width = width; imageHeader->height = height; imageHeader->nplanes = 1; imageHeader->bitspp = 24; imageHeader->compress_type = 0; imageHeader->bmp_bytesz = imageSize; imageHeader->hres = 0; imageHeader->vres = 0; imageHeader->ncolors = 0; imageHeader->nimpcolors = 0; memcpy(image + 54, WarpImg->imageData, imageSize); jbooleanArray bytes = env->NewBooleanArray(fileSize); if (bytes == 0) { delete[] image; return 0; } env->SetBooleanArrayRegion(bytes, 0, fileSize, (jboolean*) image); delete[] image; return bytes; } IplImage* loadPixels(int* pixels, int width, int height) { int x, y; IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); unsigned char* base = (unsigned char*) (img->imageData); unsigned char* ptr; for (y = 0; y < height; y++) { ptr = base + y * img->widthStep; for (x = 0; x < width; x++) { // blue ptr[3 * x] = pixels[x + y * width] & 0xFF; // green ptr[3 * x + 1] = pixels[x + y * width] >> 8 & 0xFF; // blue ptr[3 * x + 2] = pixels[x + y * width] >> 16 & 0xFF; } } return img; } IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data, jint width, jint height) { int *pixels = env->GetIntArrayElements(array_data, 0); if (pixels == 0) { return 0; } IplImage *image = loadPixels(pixels, width, height); env->ReleaseIntArrayElements(array_data, pixels, 0); if (image == 0) { return 0; } return image; } 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; } } здесь вызываю (JAVA): import android.app.Activity; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; public class FirstActivity extends Activity { /** Called when the activity is first created. */ private OCV opencv = new OCV(); private ImageView mImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); mImageView = (ImageView)findViewById(R.id.im); Bitmap fbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image2); int fwidth = fbitmap.getWidth(); int fheight = fbitmap.getHeight(); int[] fpixels = new int[fwidth * fheight]; fbitmap.getPixels(fpixels, 0, fwidth, 0, 0, fwidth, fheight); fbitmap.recycle(); Bitmap sbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); int swidth = sbitmap.getWidth(); int sheight = sbitmap.getHeight(); int[] spixels = new int[swidth * sheight]; sbitmap.getPixels(spixels, 0, swidth, 0, 0, swidth, sheight); sbitmap.recycle(); opencv.setSourceImage(fpixels, fwidth, fheight); opencv.setSourceImageTwo(spixels, swidth, sheight); opencv.extractSURFFeature(); byte[] imageData = opencv.getSourceImage(); sbitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); mImageView.setImageBitmap(sbitmap); } } extractSURFFeature() <-- здесь склеивает, просто название не поменял =) Очень прошу помочь - 2 недели до сдачи =(
  13. OpenCV_Android_склейка

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

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

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

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

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

    Заработало =) Вот код: #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <cv.h> #include <cvaux.h> #include <highgui.h> #include <cxcore.h> #include "bmpfmt.h" typedef struct MATCH_PAIR { int nA; int nB; } MATCH_PAIR; extern "C"{ CvScalar colors[] = {{{0,0,255}},{{255,255,255}}}; IplImage* WarpImg = NULL; IplImage* pImage1 = NULL; IplImage* pImage2 = NULL; IplImage* loadPixels(int* pixels, int width, int height); IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data, jint width, jint height); 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); JNIEXPORT void JNICALL Java_com_first_cv_OCV_extractSURFFeature(JNIEnv* env, jobject thiz) { CvMemStorage* storage = cvCreateMemStorage(0); CvSURFParams params = cvSURFParams(700, 0); IplImage *pWorkImage1 = cvCreateImage(cvGetSize(pImage1),IPL_DEPTH_8U,1); cvCvtColor(pImage1,pWorkImage1,CV_BGR2GRAY); CvSeq *imageKeypoints1 = 0, *imageDescriptors1 = 0; cvExtractSURF( pWorkImage1, 0, &imageKeypoints1, &imageDescriptors1, storage, params ); cvReleaseImage(&pWorkImage1); /** int i; CvSURFPoint *r; CvPoint center; for( int i = 0; i < imageKeypoints1->total; i++ ) { r = (CvSURFPoint*)cvGetSeqElem( imageKeypoints1, i ); center.x = cvRound(r->pt.x); center.y = cvRound(r->pt.y); cvCircle( pImage1, center, 1, CV_RGB(0,200,0), 1, CV_AA, 0 ); } */ IplImage *pWorkImage2 = cvCreateImage(cvGetSize(pImage2),IPL_DEPTH_8U,1); cvCvtColor(pImage2,pWorkImage2,CV_BGR2GRAY); CvSeq *imageKeypoints2 = 0, *imageDescriptors2 = 0; cvExtractSURF( pWorkImage2, 0, &imageKeypoints2, &imageDescriptors2, storage, params ); cvReleaseImage(&pWorkImage2); /** for( int i = 0; i < imageKeypoints2->total; i++ ) { r = (CvSURFPoint*)cvGetSeqElem( imageKeypoints2, i ); center.x = cvRound(r->pt.x); center.y = cvRound(r->pt.y); cvCircle( pImage2, center, 1, CV_RGB(0,200,0), 1, CV_AA, 0 ); } */ CvSURFPoint* surf1; CvSURFPoint* surf2; MATCH_PAIR *pMatchPair = new MATCH_PAIR[imageKeypoints1->total]; int descriptor_size = params.extended? 128 : 64; int nMatchingCount = FindMatchingPoints(imageKeypoints1, imageDescriptors1, imageKeypoints2, imageDescriptors2, 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(imageKeypoints1, pMatchPair[k].nA); x1 = cvRound(surf1->pt.x); y1 = cvRound(surf1->pt.y); surf2 = (CvSURFPoint*) cvGetSeqElem(imageKeypoints2, pMatchPair[k].nB); x2 = cvRound(surf2->pt.x) + pImage1->width; y2 = cvRound(surf2->pt.y); CvPoint r1 = cvPoint(x1, y1); CvPoint r2 = cvPoint(x2, y2); pt1[k] = surf1->pt; pt2[k] = surf2->pt; } delete pMatchPair; CvMat M1, M2; double H[9]; CvMat mxH = cvMat(3, 3, CV_32F, H); M1 = cvMat(1, nMatchingCount, CV_32FC2, pt1); M2 = cvMat(1, nMatchingCount, CV_32FC2, pt2); delete pt1; delete pt2; cvFindHomography(&M1, &M2, &mxH, CV_RANSAC,2); IplImage* WarpImg = cvCreateImage(cvSize(pImage1->width*2, pImage1->height*2), pImage1->depth, pImage1->nChannels); cvWarpPerspective(pImage1, WarpImg, &mxH); cvSetImageROI(WarpImg, cvRect(0, 0, pImage2->width, pImage2->height)); cvCopy(pImage2, WarpImg); cvResetImageROI(WarpImg); cvSaveImage("/sdcard/out.jpg",WarpImg); cvReleaseMemStorage(&storage); //cvReleaseImage(&pImage1); cvReleaseImage(&pImage2); } JNIEXPORT jboolean JNICALL Java_com_first_cv_OCV_setSourceImage(JNIEnv* env, jobject thiz, jintArray photo_data, jint width, jint height) { if (pImage1 != NULL) { cvReleaseImage(&pImage1); pImage1 = NULL; } pImage1 = getIplImageFromIntArray(env, photo_data, width, height); if (pImage1 == NULL) { return 0; } return 1; } JNIEXPORT jboolean JNICALL Java_com_first_cv_OCV_setSourceImageTwo(JNIEnv* env, jobject thiz, jintArray photo_datas, jint widths, jint heights) { if (pImage2 != NULL) { cvReleaseImage(&pImage2); pImage2 = NULL; } pImage2 = getIplImageFromIntArray(env, photo_datas, widths, heights); if (pImage2 == NULL) { return 0; } return 1; } JNIEXPORT jbooleanArray JNICALL Java_com_first_cv_OCV_getSourceImage(JNIEnv* env, jobject thiz) { if (pImage1 == NULL) { return 0; } cvFlip(pImage1); int width = pImage1->width; int height = pImage1->height; int rowStep = pImage1->widthStep; int headerSize = 54; int imageSize = rowStep * height; int fileSize = headerSize + imageSize; unsigned char* image = new unsigned char[fileSize]; struct bmpfile_header* fileHeader = (struct bmpfile_header*) (image); fileHeader->magic[0] = 'B'; fileHeader->magic[1] = 'M'; fileHeader->filesz = fileSize; fileHeader->creator1 = 0; fileHeader->creator2 = 0; fileHeader->bmp_offset = 54; struct bmp_dib_v3_header_t* imageHeader = (struct bmp_dib_v3_header_t*) (image + 14); imageHeader->header_sz = 40; imageHeader->width = width; imageHeader->height = height; imageHeader->nplanes = 1; imageHeader->bitspp = 24; imageHeader->compress_type = 0; imageHeader->bmp_bytesz = imageSize; imageHeader->hres = 0; imageHeader->vres = 0; imageHeader->ncolors = 0; imageHeader->nimpcolors = 0; memcpy(image + 54, pImage1->imageData, imageSize); jbooleanArray bytes = env->NewBooleanArray(fileSize); if (bytes == 0) { delete[] image; return 0; } env->SetBooleanArrayRegion(bytes, 0, fileSize, (jboolean*) image); delete[] image; return bytes; } IplImage* loadPixels(int* pixels, int width, int height) { int x, y; IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); unsigned char* base = (unsigned char*) (img->imageData); unsigned char* ptr; for (y = 0; y < height; y++) { ptr = base + y * img->widthStep; for (x = 0; x < width; x++) { // blue ptr[3 * x] = pixels[x + y * width] & 0xFF; // green ptr[3 * x + 1] = pixels[x + y * width] >> 8 & 0xFF; // blue ptr[3 * x + 2] = pixels[x + y * width] >> 16 & 0xFF; } } return img; } IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data, jint width, jint height) { int *pixels = env->GetIntArrayElements(array_data, 0); if (pixels == 0) { return 0; } IplImage *image = loadPixels(pixels, width, height); env->ReleaseIntArrayElements(array_data, pixels, 0); if (image == 0) { return 0; } return image; } 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; } } Всем спасибо за помощь =)
  19. OpenCV_Android_склейка

    Подскажите как, а то у меня уже мозги отказываются работать Вот так? if((&M1 != NULL) && (&M2 != NULL)) { cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2); }
  20. OpenCV_Android_склейка

    Коментил пошагово код. Приложение закрывается здесь: cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2); // что-то с нахождением матрицы гомографии /** IplImage* WarpImg = cvCreateImage(cvSize(pImage1->width*2, pImage1->height*2), pImage1->depth, pImage1->nChannels); cvWarpPerspective(pImage1, WarpImg, &mxH); cvSetImageROI(WarpImg, cvRect(0, 0, pImage2->width, pImage2->height)); cvCopy(pImage2, WarpImg); cvResetImageROI(WarpImg); Есть какие-нибудь предложения?
  21. OpenCV_Android_склейка

    А на перевый взгляд что из этого кода можно убрать? Супер-качество мне не нужно. Так как делаю на мобильник, хочу сэкономить везде, где можно.
  22. OpenCV_Android_склейка

    Такой вопрос: обязательно ли находить пары точек до нахождения матрицы гомографии в opencv? Над логами я подумаю, но это может не решить проблему
  23. OpenCV_Android_склейка

    Определить не смог, так как отлаживаю на телефоне (на эмуляторе просто не запускается). Знаю точно, что нахождение ключевых точек и дескрипторов идет нормально. А вот дальше трудно сказать - может памяти много жрет. Может можно упростить как-то - изначально ведь код склейки писался не для мобильника. Изображения подгружаю небольшие - 500х300. Уже нервный тик заработал =(
  24. Попытался собрать из разных кусков вот такой код, но он не работает: #include <string.h> #include <jni.h> #include <android/log.h> #include <vector> #include <opencv/cv.h> #include <opencv/ml.h> #include <opencv/cvaux.h> #include <opencv/highgui.h> #include <opencv/cxcore.h> #include "bmpfmt.h" #define ANDROID_LOG_VERBOSE ANDROID_LOG_DEBUG #define LOG_TAG "CVJNI" #define LOGV(...) __android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #ifdef __cplusplus extern "C" { #endif IplImage* pImage = NULL; IplImage* pImage2 = NULL; IplImage* img_out = NULL; IplImage* loadPixels(int* pixels, int width, int height); IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data,jint width, jint height); void flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, std::vector<int>& ptpairs ); JNIEXPORT void JNICALL Java_com_ex1_OCV_Stitch(JNIEnv* env, jobject thiz) { IplImage *pWorkImage = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1); cvCvtColor(pImage,pWorkImage,CV_BGR2GRAY); IplImage *pWorkImage2 = cvCreateImage(cvGetSize(pImage2),IPL_DEPTH_8U,1); cvCvtColor(pImage2,pWorkImage2,CV_BGR2GRAY); int width1 = pWorkImage->width; int height1 = pWorkImage->height; int width2 = pWorkImage2->width; int height2 = pWorkImage2->height; CvMemStorage* storage = cvCreateMemStorage(0); CvSeq *imageKeypoints = 0, *imageDescriptors = 0; CvSeq *imageKeypoints2 = 0, *imageDescriptors2 = 0; CvSURFParams params = cvSURFParams(3000, 0); cvExtractSURF( pWorkImage, 0, &imageKeypoints, &imageDescriptors, storage, params ); cvExtractSURF( pWorkImage2, 0, &imageKeypoints2, &imageDescriptors2, storage, params ); // нахождение пар std::vector<int> ptpairs; //проверить функцию.возможно переписать. flannFindPairs( imageKeypoints, imageDescriptors, imageKeypoints2, imageDescriptors2, ptpairs ); // быстрее чем брутфорсный перебор // функцию не проверял //считаем матрицу гомографии int c_point_count = ((int)ptpairs.size())/2; CvMat* points = cvCreateMat(2, c_point_count, CV_32FC1); CvMat* points2 = cvCreateMat(2, c_point_count, CV_32FC1); for( int i = 0; i < (int)ptpairs.size(); i += 2) { CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i]); CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints2, ptpairs[i+1]); cvmSet(points,0,i/2,r1->pt.x); cvmSet(points,1,i/2,r1->pt.y); cvmSet(points2,0,i/2,r2->pt.x); cvmSet(points2,1,i/2,r2->pt.y); } CvMat* homography_matrix = cvCreateMat(3, 3, CV_32FC1); cvFindHomography(points2, points, homography_matrix, CV_RANSAC, 1); //cvFindHomography(points1, points2, homography_matrix, CV_RANSAC, RANSAC_ERR);// матрица наоборот? //вся матрица гомографии int m11=CV_MAT_ELEM( *homography_matrix, float, 0, 0 );// int m12=CV_MAT_ELEM( *homography_matrix, float, 0, 1 );// int m13=CV_MAT_ELEM( *homography_matrix, float, 0, 2 );//сдвиг по х int m21=CV_MAT_ELEM( *homography_matrix, float, 1, 0 );// int m22=CV_MAT_ELEM( *homography_matrix, float, 1, 1 );// int m23=CV_MAT_ELEM( *homography_matrix, float, 1, 2 );//сдвиг по у int m31=CV_MAT_ELEM( *homography_matrix, float, 2, 0 );// int m32=CV_MAT_ELEM( *homography_matrix, float, 2, 1 );// int m33=CV_MAT_ELEM( *homography_matrix, float, 2, 2 );// img_out=cvCreateImage(cvSize(width1+width2,height1+height2),IPL_DEPTH_8U,1); cvWarpPerspective(pImage2,img_out,homography_matrix,CV_WARP_FILL_OUTLIERS,cvScalarAll(0)); cvSetImageROI(img_out,cvRect(0,0,width1,height1)); cvCopy(pImage,img_out); cvResetImageROI(img_out); //конец. удаляем все cvReleaseImage(&pImage); cvReleaseImage(&pImage2); //удалить точки и дескрипторы (правильно через cvClearSeq или через cvReleaseMemStorage или cvClearMemStorage?) cvClearSeq(imageKeypoints); cvClearSeq(imageKeypoints2); cvClearSeq(imageDescriptors); cvClearSeq(imageDescriptors2); cvClearMemStorage(storage); cvReleaseMemStorage(&storage); cvReleaseImage(&pWorkImage); cvReleaseImage(&pWorkImage2); } JNIEXPORT jboolean JNICALL Java_com_ex1_OCV_setSourceImage(JNIEnv* env, jobject thiz, jintArray photo_data, jint width, jint height) { if (pImage != NULL) { cvReleaseImage(&pImage); pImage = NULL; } pImage = getIplImageFromIntArray(env, photo_data, width, height); if (pImage == NULL) { return 0; } LOGI("Load Image Done."); return 1; } JNIEXPORT jboolean JNICALL Java_com_ex1_OCV_setSourceImage2(JNIEnv* env, jobject thiz, jintArray photo_data, jint width, jint height) { if (pImage2 != NULL) { cvReleaseImage(&pImage2); pImage2 = NULL; } pImage2 = getIplImageFromIntArray(env, photo_data, width, height); if (pImage2 == NULL) { return 0; } LOGI("Load Image Done."); return 1; } JNIEXPORT jbooleanArray JNICALL Java_com_ex1_OCV_getSourceImage(JNIEnv* env, jobject thiz) { if (img_out == NULL) { LOGE("No source image."); return 0; } cvFlip(img_out); int width = img_out->width; int height = img_out->height; int rowStep = img_out->widthStep; int headerSize = 54; int imageSize = rowStep * height; int fileSize = headerSize + imageSize; unsigned char* image = new unsigned char[fileSize]; struct bmpfile_header* fileHeader = (struct bmpfile_header*) (image); fileHeader->magic[0] = 'B'; fileHeader->magic[1] = 'M'; fileHeader->filesz = fileSize; fileHeader->creator1 = 0; fileHeader->creator2 = 0; fileHeader->bmp_offset = 54; struct bmp_dib_v3_header_t* imageHeader = (struct bmp_dib_v3_header_t*) (image + 14); imageHeader->header_sz = 40; imageHeader->width = width; imageHeader->height = height; imageHeader->nplanes = 1; imageHeader->bitspp = 24; imageHeader->compress_type = 0; imageHeader->bmp_bytesz = imageSize; imageHeader->hres = 0; imageHeader->vres = 0; imageHeader->ncolors = 0; imageHeader->nimpcolors = 0; memcpy(image + 54, img_out->imageData, imageSize); jbooleanArray bytes = env->NewBooleanArray(fileSize); if (bytes == 0) { LOGE("Error in creating the image."); delete[] image; return 0; } env->SetBooleanArrayRegion(bytes, 0, fileSize, (jboolean*) image); delete[] image; return bytes; } IplImage* loadPixels(int* pixels, int width, int height) { int x, y; IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); unsigned char* base = (unsigned char*) (img->imageData); unsigned char* ptr; for (y = 0; y < height; y++) { ptr = base + y * img->widthStep; for (x = 0; x < width; x++) { // blue ptr[3 * x] = pixels[x + y * width] & 0xFF; // green ptr[3 * x + 1] = pixels[x + y * width] >> 8 & 0xFF; // blue ptr[3 * x + 2] = pixels[x + y * width] >> 16 & 0xFF; } } return img; } IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data, jint width, jint height) { int *pixels = env->GetIntArrayElements(array_data, 0); if (pixels == 0) { LOGE("Error getting int array of pixels."); return 0; } IplImage *image = loadPixels(pixels, width, height); env->ReleaseIntArrayElements(array_data, pixels, 0); if (image == 0) { LOGE("Error loading pixel array."); return 0; } return image; } void flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, std::vector<int>& ptpairs ) { int length = (int)(objectDescriptors->elem_size/sizeof(float)); cv::Mat m_object(objectDescriptors->total, length, CV_32F); cv::Mat m_image(imageDescriptors->total, length, CV_32F); // copy descriptors CvSeqReader obj_reader; float* obj_ptr = m_object.ptr<float>(0); cvStartReadSeq( objectDescriptors, &obj_reader ); for(int i = 0; i < objectDescriptors->total; i++ ) { const float* descriptor = (const float*)obj_reader.ptr; CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader ); memcpy(obj_ptr, descriptor, length*sizeof(float)); obj_ptr += length; } CvSeqReader img_reader; float* img_ptr = m_image.ptr<float>(0); cvStartReadSeq( imageDescriptors, &img_reader ); for(int i = 0; i < imageDescriptors->total; i++ ) { const float* descriptor = (const float*)img_reader.ptr; CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader ); memcpy(img_ptr, descriptor, length*sizeof(float)); img_ptr += length; } } #ifdef __cplusplus } #endif Подскажите что не так, а то мозг уже отказывается думать (говорю сразу, что новичек) Здесь вызываю: package com.ex1; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.widget.ImageView; public class Ex1Activity extends Activity { /** Called when the activity is first created. */ private OCV opencv = new OCV(); private ImageView mImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.i1); Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.i2); int width1 = bitmap1.getWidth(); int height1 = bitmap1.getHeight(); int width2 = bitmap2.getWidth(); int height2 = bitmap2.getHeight(); int[] pixels1 = new int[width1 * height1]; int[] pixels2 = new int[width2 * height2]; bitmap1.getPixels(pixels1, 0, width1, 0, 0, width1, height1); bitmap2.getPixels(pixels2, 0, width2, 0, 0, width2, height2); opencv.setSourceImage(pixels1, width1, height1); opencv.setSourceImage2(pixels2, width2, height2); opencv.Stitch(); byte[] imageData = opencv.getSourceImage(); bitmap1.recycle(); bitmap2.recycle(); Bitmap bitmap3 = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); mImageView.setImageBitmap(bitmap3); } } Прога закрывается и все
  25. Нашел такую прогу ссылка Можно ли вытащить из неё склейку? Уж этот код точно должен на андроиде пойти
×