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

OpenCV_Android_склейка

Recommended Posts

Народ, очень срочно нужна помощь! Пытаюсь склеить 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 недели до сдачи =(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А "определенный момент" определили?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А "определенный момент" определили?

Определить не смог, так как отлаживаю на телефоне (на эмуляторе просто не запускается). Знаю точно, что нахождение ключевых точек и дескрипторов идет нормально. А вот дальше трудно сказать - может памяти много жрет. Может можно упростить как-то - изначально ведь код склейки писался не для мобильника. Изображения подгружаю небольшие - 500х300. Уже нервный тик заработал =(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а эмулятора\тестовой среды для андройда нету?

для айфона и вин мобайл вроде бы даже в комплекте идут.

попробуйте выводить в лог какие строчки прошли и определите хотя бы где падает, если не можете в дебаге проверить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а эмулятора\тестовой среды для андройда нету?

для айфона и вин мобайл вроде бы даже в комплекте идут.

попробуйте выводить в лог какие строчки прошли и определите хотя бы где падает, если не можете в дебаге проверить.

Такой вопрос: обязательно ли находить пары точек до нахождения матрицы гомографии в opencv?

Над логами я подумаю, но это может не решить проблему

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обязательно.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обязательно.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно поиграть с параметром SURF-а

CvSURFParams params = cvSURFParams(1000, 0);

поставить порог повыше, и точек будет меньше.

Или использовать другие, более простые дескрипторы (Star,Hsrris,FAST,...), благо их там целая куча.

ЗЫ: SURF - кстати, возможно потребует лицензии для коммерческого использования.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно поиграть с параметром SURF-а

CvSURFParams params = cvSURFParams(1000, 0);

поставить порог повыше, и точек будет меньше.

Или использовать другие, более простые дескрипторы (Star,Hsrris,FAST,...), благо их там целая куча.

ЗЫ: SURF - кстати, возможно потребует лицензии для коммерческого использования.

Коментил пошагово код. Приложение закрывается здесь:


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);

Есть какие-нибудь предложения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хорошо было бы проверку M1 и M2 приделать, а то может они пустые.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хорошо было бы проверку M1 и M2 приделать, а то может они пустые.

Подскажите как, а то у меня уже мозги отказываются работать

Вот так?


if((&M1 != NULL) && (&M2 != NULL))

        {

		cvFindHomography(&M1, &M2, &mxH, CV_RANSAC, 2);

        }

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Надо свойство rows и cols проверить у матриц, можно просто значение imageKeypoints1->total посмотреть, а лучше и то, и другое.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Заработало =)

Вот код:


#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;

}


}


Всем спасибо за помощь =)



Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Надо смотреть заголовки

Спецификацию формата можно найти здесь:

http://www.w3.org/TR/PNG/

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Надо смотреть заголовки

Спецификацию формата можно найти здесь:

http://www.w3.org/TR/PNG/

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

Это может как-то приводить к ошибке?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю что может.

Можно попробовать флаги установить в функции загрузки, чтобы альфу не грузил, но вообще то он сам должен определять количество слоев.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю что может.

Можно попробовать флаги установить в функции загрузки, чтобы альфу не грузил, но вообще то он сам должен определять количество слоев.

Тесты проги завели мобилу в циклический ребут, перепрошил и изображения начали нормально загружаться - просто чудо расчудесное :D

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

вроде называется bundle adjustment, но не уверен, вообщем это шаг когда панораму пытаются развернуть в прямоугольник.

тут http://www.cs.bath.ac.uk/brown/papers/ijcv2007.pdf

секция 5 Automatic Panorama Straightening

я так понимаю, что сначала вычисляется отношение между чистыми парами изображений панорамы, а потом имея преобразование одно относительно другого мы каких то образом всё это проэцируем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

вроде называется bundle adjustment, но не уверен, вообщем это шаг когда панораму пытаются развернуть в прямоугольник.

тут http://www.cs.bath.ac.uk/brown/papers/ijcv2007.pdf

секция 5 Automatic Panorama Straightening

я так понимаю, что сначала вычисляется отношение между чистыми парами изображений панорамы, а потом имея преобразование одно относительно другого мы каких то образом всё это проэцируем.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

реализация есть+там есть blending, появилось в каких то последних версиях вроде бы называется модуль stitching(на форуме тоже обсуждалось), вы старый код используете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

реализация есть+там есть blending, появилось в каких то последних версиях вроде бы называется модуль stitching(на форуме тоже обсуждалось), вы старый код используете.

Я знаю про этот модуль, но мне нужно реализовать без него

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×