| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 | 
							- #include "ImageTailor.h"
 
- #include <libyuv.h>
 
- #include "OptimizeCal.h"
 
- #include "FusionAndTailor.cuh"
 
- std::mutex g_CurFrameMutex;
 
- std::mutex g_PanoMutex;
 
- ImageTailor::ImageTailor()
 
- {
 
- 	pPanoImageBuffer = NULL;
 
- 	pTailorThread = NULL;
 
- 	this->bTailorThreadOut = true;
 
- 	StartTailorThread();
 
- 	bTailorThreadWork = false;
 
- }
 
- ImageTailor::~ImageTailor()
 
- {
 
- 	this->bTailorThreadOut = false;
 
- 	if (pTailorThread->joinable())
 
- 		pTailorThread->join();
 
- 	if (pTailorThread!=NULL)
 
- 	{
 
- 		delete pTailorThread;
 
- 		pTailorThread = NULL;
 
- 	}
 
- 	if (pPanoImageBuffer != NULL)
 
- 	{
 
- 		delete[] pPanoImageBuffer;
 
- 		cudaFree(pPanoImageBufferInGpu);
 
- 		pPanoImageBuffer = NULL;
 
- 	}
 
- }
 
- void ImageTailor::Init(unsigned char* pImage, int nPanoWidth, int nPanoHeight, cv::Point cvLeftTop)
 
- {
 
- 	//get the pointer
 
- 	pPanoImageBuffer = pImage;
 
- 	//get the width
 
- 	this->nPanoWidth = nPanoWidth;
 
- 	//get the height
 
- 	this->nPanoHeight = nPanoHeight;
 
- 	//get the lefttop point
 
- 	this->LeftTop = cvLeftTop;
 
- 	//get the panoimage pitch
 
- 	this->nPanoPitch = (nPanoWidth*3 + 3) / 4 * 4;
 
- }
 
- void ImageTailor::Init_Gpu(unsigned char* pImage, unsigned char* pImageGpu, int nPanoWidth, int nPanoHeight, cv::Point cvLeftTop)
 
- {
 
- 	//get the pointer
 
- 	pPanoImageBuffer = pImage;
 
- 	//get the width
 
- 	this->nPanoWidth = nPanoWidth;
 
- 	//get the height
 
- 	this->nPanoHeight = nPanoHeight;
 
- 	//get the lefttop point
 
- 	this->LeftTop = cvLeftTop;
 
- 	//get the panoimage pitch
 
- 	this->nPanoPitch = (nPanoWidth * 3 + 3) / 4 * 4;
 
- 	pPanoImageBufferInGpu = pImageGpu;
 
- }
 
- int ImageTailor::StitchingOnPano(cv::Point LeftTop, cv::Mat* FrameImage,std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	//in the paon image ,the lefttop point is (0,0),stitching the image on the pano image
 
- 	//get the lefttop point
 
- 	cv::Point cvLeftTop = LeftTop;
 
- 	//get the width
 
- 	int nFrameWidth = FrameImage->cols;
 
- 	//get the height
 
- 	int nFrameHeight = FrameImage->rows;
 
- 	//get the pitch
 
- 	int nFramePitch = FrameImage->step[0];
 
- 	//set a pointer to pano image stitching target
 
- 	unsigned char* pPanoImageTarget = pPanoImageBuffer + cvLeftTop.y * nPanoPitch + cvLeftTop.x * 3;
 
- 	cv::Mat PanoImage = cv::Mat(nPanoHeight, nPanoWidth, CV_8UC3, pPanoImageBuffer);
 
- 	//stitching the image
 
- 	for (int i = 0; i < nFrameHeight; i++)
 
- 	{
 
- 		//get this line overlap 
 
- 		std::vector<int>& vOverlap = (*pvvOverlap)[i];
 
- 		//copy the image
 
- 		
 
- 		FastCopy_Any(FrameImage->ptr<uchar>(i) + vOverlap[0] * 3
 
- 			, pPanoImageTarget + nPanoPitch * i + vOverlap[0] * 3
 
- 			, (vOverlap[1]- vOverlap[0]) * 3);
 
- 		
 
- 	}
 
- 	return 0;
 
- }
 
- int ImageTailor::StitchingOnPanoYUV(cv::Point LeftTop, unsigned char* pImage, int nWidth, int nHeight, int nPitch, std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	//get Y,U,V pointer in pano image
 
- 	unsigned char* pPanoImageY = pPanoImageBuffer;
 
- 	unsigned char* pPanoImageU = pPanoImageBuffer + nPanoPitch * nPanoHeight;
 
- 	unsigned char* pPanoImageV = pPanoImageBuffer + nPanoPitch * nPanoHeight * 5 / 4;
 
- 	cv::Mat panoImage(nPanoHeight * 3 / 2, nPanoWidth, CV_8U, pPanoImageBuffer);
 
- 	//get Y,U,V pointer in frame image
 
- 	unsigned char* pFrameImageY = pImage;
 
- 	unsigned char* pFrameImageU = pImage + nPitch * nHeight;
 
- 	unsigned char* pFrameImageV = pImage + nPitch * nHeight * 5 / 4;
 
- 	//Disassembly the pvvOverlap in rect to calculate the planepaste
 
- 	std::vector<cv::Rect> vPastePart;
 
- 	int nPanoImageHeight = int(pvvOverlap->size());
 
- 	cv::Rect rectPastePart;
 
- 	bool bChangeFlags = true;
 
- 	for (int i = 0; i < nPanoImageHeight; i++)
 
- 	{
 
- 		std::vector<int>& vOverlap = (*pvvOverlap)[i];
 
- 		if (rectPastePart.x != vOverlap[0]
 
- 			&& rectPastePart.y != vOverlap[1])
 
- 			bChangeFlags = true;
 
- 		if (bChangeFlags)
 
- 		{
 
- 			if (i != 0)
 
- 				vPastePart.push_back(rectPastePart);
 
- 			rectPastePart.x = vOverlap[0];
 
- 			rectPastePart.width = vOverlap[1] - vOverlap[0];
 
- 			rectPastePart.y = i;
 
- 			rectPastePart.height = 0;
 
- 			bChangeFlags = false;
 
- 		}
 
- 		rectPastePart.height++;
 
- 	}
 
- 	vPastePart.push_back(rectPastePart);
 
- 	int nPartNum = (int)vPastePart.size();
 
- 	for (int i = 0; i < nPartNum; i++)
 
- 	{
 
- 		cv::Rect& CurPart = vPastePart[i];
 
- 		//panoImage pointer
 
- 		unsigned char* pPanoImageTargetY = pPanoImageY + (CurPart.y + LeftTop.y) * nPanoPitch + (CurPart.x + LeftTop.x);
 
- 		unsigned char* pPanoImageTargetU = pPanoImageU + (CurPart.y + LeftTop.y) * nPanoPitch / 4 + (CurPart.x + LeftTop.x) / 2;
 
- 		unsigned char* pPanoImageTargetV = pPanoImageV + (CurPart.y + LeftTop.y) * nPanoPitch / 4 + (CurPart.x + LeftTop.x) / 2;
 
- 		//frameImage pointer 
 
- 		unsigned char* pFrameImageTargetY = pFrameImageY + CurPart.y * nPitch + CurPart.x;
 
- 		unsigned char* pFrameImageTargetU = pFrameImageU + CurPart.y * nPitch / 4 + CurPart.x / 2;
 
- 		unsigned char* pFrameImageTargetV = pFrameImageV + CurPart.y * nPitch / 4 + CurPart.x / 2;
 
- 		//copy the Y plane
 
- 		libyuv::CopyPlane(
 
- 			pPanoImageTargetY, nPanoPitch,
 
- 			pFrameImageTargetY, nPitch,
 
- 			CurPart.width, CurPart.height
 
- 		);
 
- 		//copy the U plane
 
- 		libyuv::CopyPlane(
 
- 			pPanoImageTargetU, nPanoPitch / 2,
 
- 			pFrameImageTargetU, nPitch / 2,
 
- 			CurPart.width / 2, CurPart.height / 2
 
- 		);
 
- 		//copy the V plane
 
- 		libyuv::CopyPlane(
 
- 			pPanoImageTargetV, nPanoPitch / 2,
 
- 			pFrameImageTargetV, nPitch / 2,
 
- 			CurPart.width / 2, CurPart.height / 2
 
- 		);
 
- 	}
 
- 	
 
- 	return 0;
 
- }
 
- int ImageTailor::StitchingOnPanoYUV(cv::Point LeftTop, cv::Mat* FrameImage, std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	//get Y,U,V pointer in pano image
 
- 	unsigned char* pPanoImageY = pPanoImageBuffer;
 
- 	unsigned char* pPanoImageU = pPanoImageBuffer + ALIGN_4(nPanoWidth) * nPanoHeight;
 
- 	unsigned char* pPanoImageV = pPanoImageBuffer + ALIGN_4(nPanoWidth) * nPanoHeight * 5 / 4;
 
- 	cv::Mat panoImage(nPanoHeight * 3 / 2, nPanoWidth, CV_8U, pPanoImageBuffer);
 
- 	//get Y,U,V pointer in frame image
 
- 	unsigned char* &pFrameImageY = FrameImage->data;
 
- 	unsigned char* pFrameImageU = pFrameImageY + FrameImage->step * FrameImage->rows;
 
- 	unsigned char* pFrameImageV = pFrameImageY + FrameImage->step * FrameImage->rows * 5 / 4;
 
- 	//Disassembly the pvvOverlap in rect to calculate the planepaste
 
- 	std::vector<cv::Rect> vPastePart;
 
- 	int nPanoImageHeight = int(pvvOverlap->size());
 
- 	cv::Rect rectPastePart;
 
- 	bool bChangeFlags = true;
 
- 	for (int i = 0; i < nPanoImageHeight; i++)
 
- 	{
 
- 		std::vector<int>& vOverlap = (*pvvOverlap)[i];
 
- 		if (rectPastePart.x != vOverlap[0]
 
- 			&& rectPastePart.y != vOverlap[1])
 
- 			bChangeFlags = true;
 
- 		if (bChangeFlags)
 
- 		{
 
- 			if (i != 0)
 
- 				vPastePart.push_back(rectPastePart);
 
- 			rectPastePart.x = vOverlap[0];
 
- 			rectPastePart.width = vOverlap[1] - vOverlap[0];
 
- 			rectPastePart.y = i;
 
- 			rectPastePart.height = 0;
 
- 			bChangeFlags = false;
 
- 		}
 
- 		rectPastePart.height++;
 
- 	}
 
- 	vPastePart.push_back(rectPastePart);
 
- 	int nPartNum = (int)vPastePart.size();
 
- 	for (int i = 0; i < nPartNum; i++)
 
- 	{
 
- 		cv::Rect& CurPart = vPastePart[i];
 
- 		//panoImage pointer
 
- 		unsigned char* pPanoImageTargetY = pPanoImageY + (CurPart.y + LeftTop.y) * ALIGN_4(nPanoWidth) + (CurPart.x + LeftTop.x);
 
- 		unsigned char* pPanoImageTargetU = pPanoImageU + (CurPart.y + LeftTop.y) * ALIGN_4(nPanoWidth) / 4 + (CurPart.x + LeftTop.x) / 2;
 
- 		unsigned char* pPanoImageTargetV = pPanoImageV + (CurPart.y + LeftTop.y) * ALIGN_4(nPanoWidth) / 4 + (CurPart.x + LeftTop.x) / 2;
 
- 		//frameImage pointer 
 
- 		unsigned char* pFrameImageTargetY = pFrameImageY + CurPart.y * FrameImage->step + CurPart.x;
 
- 		unsigned char* pFrameImageTargetU = pFrameImageU + CurPart.y * FrameImage->step / 4 + CurPart.x / 2;
 
- 		unsigned char* pFrameImageTargetV = pFrameImageV + CurPart.y * FrameImage->step / 4 + CurPart.x / 2;
 
- 		//copy the Y plane
 
- 		libyuv::CopyPlane(
 
- 			pFrameImageTargetY, FrameImage->step,
 
- 			pPanoImageTargetY, ALIGN_4(nPanoWidth),
 
- 			CurPart.width, CurPart.height
 
- 		);
 
- 		//copy the U plane
 
- 		libyuv::CopyPlane(
 
- 			pFrameImageTargetU, FrameImage->step / 2,
 
- 			pPanoImageTargetU, ALIGN_4(nPanoWidth) / 2,
 
- 			CurPart.width / 2, CurPart.height / 2
 
- 		);
 
- 		//copy the V plane
 
- 		libyuv::CopyPlane(
 
- 			pFrameImageTargetV, FrameImage->step / 2,
 
- 			pPanoImageTargetV, ALIGN_4(nPanoWidth) / 2,
 
- 			CurPart.width / 2, CurPart.height / 2
 
- 		);
 
- 	}
 
- 	return 0;
 
- }
 
- void ImageTailor::TailorWordInThread(ImageTailor* pClass)
 
- {
 
- 	while (pClass->bTailorThreadOut)
 
- 	{
 
- 		
 
- 		g_CurFrameMutex.lock();
 
- 		g_PanoMutex.lock();
 
- 		if (pClass->qWorkQueue.size()<=0 || pClass->qWorkQueue.size() >10000)
 
- 		{
 
- 			g_CurFrameMutex.unlock();
 
- 			g_PanoMutex.unlock();
 
- 			continue;
 
- 			//pClass->ClearWorkOrder();
 
- 			
 
- 		}
 
- 		
 
- 		pClass->bTailorThreadWork = true;
 
- 	
 
- 		//WAIT_TAILOR& WorkOrder = pClass->qWorkQueue.front();
 
- 		
 
- 		
 
- 		if (!pClass->bUseYUV)
 
- 			pClass->StitchingOnPano(pClass->qWorkQueue.front().ptPosition, pClass->qWorkQueue.front().pROI, pClass->qWorkQueue.front().pvvOverlap);
 
- 		else
 
- 			pClass->StitchingOnPanoYUVByGPU(
 
- 				pClass->qWorkQueue.front().ptPosition,
 
- 				pClass->qWorkQueue.front().pImage,
 
- 				pClass->qWorkQueue.front().nWidth,
 
- 				pClass->qWorkQueue.front().nHeight,
 
- 				ALIGN_4(pClass->qWorkQueue.front().nPitch),
 
- 				pClass->qWorkQueue.front().pvvOverlap
 
- 			);
 
- 		g_CurFrameMutex.unlock();
 
- 		g_PanoMutex.unlock();
 
- 		pClass->qWorkQueue.pop();
 
- 		if (pClass->qWorkQueue.size() > 25)
 
- 			pClass->qWorkQueue.pop();
 
- 		if( pClass->qWorkQueue.size() > 50)
 
- 			pClass->qWorkQueue.pop();
 
- 		pClass->bTailorThreadWork = false;
 
- 	}
 
- }
 
- /// <summary>
 
- /// Stitchings the on pano.
 
- /// </summary>
 
- /// <param name="LeftTop">The left top.</param>
 
- /// <param name="FrameImage">The frame image.</param>
 
- /// <param name="nWidth">Width of the n.</param>
 
- /// <param name="nHeight">Height of the n.</param>
 
- /// <param name="nPitch">The n pitch.</param>
 
- /// <param name="pvvOverlap">The PVV overlap.</param>
 
- /// <returns></returns>
 
- int ImageTailor::StitchingOnPanoYUVByGPU(cv::Point LeftTop, unsigned char* FrameImage, int nWidth, int nHeight, int nPitch, std::vector<std::vector<int>>* pvvOverlap)
 
- {	
 
- 	
 
- 	//get Y,U,V pointer in pano image
 
- 	unsigned char* pPanoImageY = pPanoImageBufferInGpu + LeftTop.y * ALIGN_4(nPanoWidth) + LeftTop.x;
 
- 	unsigned char* pPanoImageU = pPanoImageBufferInGpu + ALIGN_4(nPanoWidth) * nPanoHeight + LeftTop.y/2 * (ALIGN_4(nPanoWidth)/2) + LeftTop.x/2;
 
- 	unsigned char* pPanoImageV = pPanoImageBufferInGpu + ALIGN_4(nPanoWidth) * nPanoHeight * 5 / 4 + LeftTop.y / 2 * (ALIGN_4(nPanoWidth) / 2) + LeftTop.x / 2;
 
- 	//cv::Mat panoImage(nPanoHeight * 3 / 2, nPanoWidth, CV_8U, pPanoImageBuffer);
 
- 	unsigned char*& pFrameImageY = FrameImage;
 
- 	unsigned char* pFrameImageU = pFrameImageY + nPitch * nHeight;
 
- 	unsigned char* pFrameImageV = pFrameImageY + nPitch * nHeight * 5 / 4;
 
- 	//Disassembly the pvvOverlap in rect to calculate the planepaste
 
- 	std::vector<cv::Rect> vPastePart;
 
- 	int nPanoImageHeight = int(pvvOverlap->size());
 
- 	cv::Rect rectPastePart;
 
- 	bool bChangeFlags = true;
 
- 	for (int i = 0; i < nPanoImageHeight; i++)
 
- 	{
 
- 		std::vector<int>& vOverlap = (*pvvOverlap)[i];
 
- 		if (rectPastePart.x != vOverlap[0]
 
- 			&& rectPastePart.y != vOverlap[1])
 
- 			bChangeFlags = true;
 
- 		if (bChangeFlags)
 
- 		{
 
- 			if (i != 0)
 
- 				vPastePart.push_back(rectPastePart);
 
- 			rectPastePart.x = vOverlap[0];
 
- 			rectPastePart.width = vOverlap[1] - vOverlap[0];
 
- 			rectPastePart.y = i;
 
- 			rectPastePart.height = 0;
 
- 			bChangeFlags = false;
 
- 		}
 
- 		rectPastePart.height++;
 
- 	}
 
- 	vPastePart.push_back(rectPastePart);
 
- 	int nBlockCount =int(vPastePart.size());
 
- 	for (int i = 0; i < nBlockCount; i++)
 
- 	{
 
- 		cv::Rect CurPart = vPastePart[i];
 
- 		int nPasteWidth = CurPart.width;
 
- 		int nPasteHeight = CurPart.height;
 
- 		int nPasteLeft = CurPart.x;
 
- 		int nPasteTop = CurPart.y;
 
- 		unsigned char* pPanoImageTargetY = pPanoImageY;//; +(CurPart.y) * ALIGN_4(nPanoWidth) + (CurPart.x);
 
- 		unsigned char* pPanoImageTargetU = pPanoImageU;// +(CurPart.y) * ALIGN_4(nPanoWidth) / 4 + (CurPart.x) / 2;
 
- 		unsigned char* pPanoImageTargetV = pPanoImageV;// +(CurPart.y) * ALIGN_4(nPanoWidth) / 4 + (CurPart.x) / 2;
 
- 		//frameImage pointer 
 
- 		unsigned char* pFrameImageTargetY = pFrameImageY + CurPart.y * nPitch + CurPart.x;
 
- 		unsigned char* pFrameImageTargetU = pFrameImageU + CurPart.y * nPitch / 4 + CurPart.x / 2;
 
- 		unsigned char* pFrameImageTargetV = pFrameImageV + CurPart.y * nPitch / 4 + CurPart.x / 2;
 
- 		YUVTailorAndBlender::CopyPlane(
 
- 			pFrameImageTargetY, nWidth, nHeight, nPitch,
 
- 			pPanoImageTargetY, nPanoWidth, nPanoHeight, ALIGN_4(nPanoWidth),
 
- 			nPasteWidth, nPasteHeight, nPasteLeft, nPasteTop,
 
- 			1, NULL
 
- 		);
 
- 		YUVTailorAndBlender::CopyPlane(
 
- 			pFrameImageTargetU, nWidth / 2, nHeight / 2, nPitch / 2,
 
- 			pPanoImageTargetU, nPanoWidth / 2, nPanoHeight / 2, ALIGN_4(nPanoWidth) / 2,
 
- 			nPasteWidth / 2, nPasteHeight / 2, nPasteLeft / 2, nPasteTop / 2,
 
- 			1, NULL
 
- 		);
 
- 		YUVTailorAndBlender::CopyPlane(
 
- 			pFrameImageTargetV, nWidth / 2, nHeight / 2, nPitch / 2,
 
- 			pPanoImageTargetV, nPanoWidth / 2, nPanoHeight / 2, ALIGN_4(nPanoWidth) / 2,
 
- 			nPasteWidth / 2, nPasteHeight / 2, nPasteLeft / 2, nPasteTop / 2,
 
- 			1, NULL
 
- 		);
 
- 		cudaError Error = cudaDeviceSynchronize();
 
- 		if (Error == 700)
 
- 			int x = 10;
 
- 	}
 
- 	return 0;
 
- }
 
- int ImageTailor::Stitching(int nPostion, cv::Mat& ROI, std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	return 0;
 
- }
 
- void ImageTailor::SetOverlap(std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	vvOverlap = *pvvOverlap;
 
- }
 
- bool ImageTailor::StartTailorThread()
 
- {
 
- 	pTailorThread = new std::thread(TailorWordInThread, this);
 
- 	return false;
 
- }
 
- bool ImageTailor::EndTailorThread()
 
- {
 
- 	if (pTailorThread->joinable())
 
- 	{
 
- 		this->bTailorThreadOut = false;
 
- 		pTailorThread->join();
 
- 		return true;
 
- 	}
 
- 	else
 
- 	{
 
- 		return false;
 
- 	}
 
- }
 
- void ImageTailor::AddWorkOrderInqueue(cv::Point LeftTop, cv::Mat* FrameImage, std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	WAIT_TAILOR WorkOrder;
 
- 	WorkOrder.ptPosition = LeftTop;
 
- 	WorkOrder.pROI = FrameImage;
 
- 	WorkOrder.pvvOverlap = pvvOverlap;
 
- 	qWorkQueue.push(WorkOrder);
 
- }
 
- void ImageTailor::ClearWorkOrder()
 
- {
 
- 	std::queue<WAIT_TAILOR>().swap(qWorkQueue);
 
- 	/*while (!qWorkQueue.empty())
 
- 	{
 
- 		qWorkQueue.pop();
 
- 	}*/
 
- }
 
- void ImageTailor::AddWorkOrderInQueueGpu(cv::Point LeftTop, unsigned char* pData, int nWidth, int nHeight, int nPitch, std::vector<std::vector<int>>* pvvOverlap)
 
- {
 
- 	WAIT_TAILOR WorkOrder;
 
- 	WorkOrder.ptPosition = LeftTop;
 
- 	WorkOrder.pImage = pData;
 
- 	WorkOrder.nWidth = nWidth;
 
- 	WorkOrder.nHeight = nHeight;
 
- 	WorkOrder.nPitch = nPitch;
 
- 	WorkOrder.pvvOverlap = pvvOverlap;
 
- 	qWorkQueue.push(WorkOrder);
 
- }
 
 
  |