コード例 #1
0
ファイル: image.cpp プロジェクト: ervanalb/ao
bool SavePng(std::string filename, const DepthImage& img)
{
    // Open up a file for writing
    FILE* output = fopen(filename.c_str(), "wb");
    if (output == NULL)
    {
        printf("Failed to open PNG file for writing (errno = %i)\n", errno);
        return false;
    }

    // Create a png pointer with the callbacks above
    png_structp png_ptr = png_create_write_struct(
        PNG_LIBPNG_VER_STRING, NULL, on_png_error, on_png_warn);
    if (png_ptr == NULL)
    {
        fprintf(stderr, "Failed to allocate png write_struct\n");
        fclose(output);
        return false;
    }

    // Create an info pointer
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        fprintf(stderr, "Failed to create png info_struct");
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(output);
        return false;
    }

    // Set physical vars
    png_set_IHDR(png_ptr, info_ptr, img.cols(), img.rows(), 16,
                 PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    png_init_io(png_ptr, output);

    const float zmax = img.maxCoeff();
    const float zmin = (img == -std::numeric_limits<float>::infinity())
            .select(DepthImage::Constant(img.rows(), img.cols(), zmax),
                    img)
            .minCoeff();

    auto scaled = (zmax == zmin)
        ? DepthImage((img - zmin) + 65535)
        : DepthImage((img - zmin) * 65534 / (zmax - zmin) + 1);
    Eigen::Array<uint16_t, Eigen::Dynamic, Eigen::Dynamic>
        pixels = scaled.cast<uint16_t>().transpose();

    std::vector<uint16_t*> rows;
    for (int i=pixels.cols() - 1; i >= 0; --i)
    {
        rows.push_back(pixels.data() + i * pixels.rows());
    }

    png_set_rows(png_ptr, info_ptr, reinterpret_cast<png_bytepp>(&rows[0]));
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_SWAP_ENDIAN, NULL);
    fclose(output);

    png_destroy_write_struct(&png_ptr, &info_ptr);
    return true;
}
コード例 #2
0
void MyKinect::ProcessDepth(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth)
{//处理深度,并修复,产生掩码
	
#ifdef DEBUG
	MyTime mt;
	mt.Reset();
	mt.Start();
#endif


	// Make sure we've received valid data
	if (m_pDepthRGBX && pBuffer && (nWidth == cDepthWidth) && (nHeight == cDepthHeight))
	{

		depthFrames++;
	 	cout << "depthFrames第" << depthFrames << "帧" << endl;
		RGBQUAD* pRGBX = m_pDepthRGBX;
		const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);
		int k1 = 0, k2 = 0; int k3 = 0, k4 = 0;

		Mat inpaintResult;//修图结果
		Mat inpaintMask;//掩码		
		Mat badMask;//错误点的掩码

		badMask = Mat::zeros(Size(nWidth, nHeight), CV_8U);
		inpaintMask = Mat::zeros(Size(nWidth, nHeight), CV_8U);
	
		/*uchar * inpaintDataMask = inpaintMask.data;
		uchar * badMaskData = badMask.data;//标记当前帧 错误点掩码
		uchar * depthMat_LastData= m_pDepthMat_Last.data;
		uchar * depthMat_LastDataMask = m_pDepthMat_LastMask.data;//前景的掩码
		*/
	/*	int a = m_pDepthMat_Last.channels();
		int b = m_pDepthMat_LastMask.channels();
		int c = badMask.channels();
		int d = inpaintMask.channels();
		cout << a << "   " << b << "   " << c << "   " << d << endl;
		*/
		//考虑到mat字节对齐,改为for
		for (int i = 0; i < nHeight;i++)
		{
			uchar * inpaintDataMask = inpaintMask.ptr<uchar>(i);
			uchar * badMaskData = badMask.ptr<uchar>(i);//标记当前帧 错误点掩码
			uchar * depthMat_LastData = m_pDepthMat_Last.ptr<uchar>(i);
			uchar * depthMat_LastDataMask = m_pDepthMat_LastMask.ptr<uchar>(i);//前景的掩码

			for (int j = 0; j < nWidth;j++)
			{
				USHORT depth = *pBuffer;
				bool maskOfPixel = 0;
				if (depth <= 0)//must error pixels
				{
					depth = 0;
					badMaskData[j] = (uchar)255;
					maskOfPixel = 1;
					k1++;
				}
				if (depth > 4500) k2++;
				depth = depth >> 4;//如何最好的将 450 -- 5500映射到 0 -255里面
				//有大量=0的点,2W多 ,

				if (depth >= 255) {//掩码赋值
					depth = 255;
				}
				BYTE intensity = static_cast<BYTE>(depth);

				//用上一帧修正
				if (maskOfPixel)
				{//深度有误
					k3++;
					
					//上一帧的修复只能对背景用,不能对运动的用
					//if ((depthMat_LastDataMask[j]) == 0)//是背景
					//重要的地方就是 人运动的边缘,而这都是前景区域了。		
					
					{//这两个是8u3c的
						intensity = (depthMat_LastData[j*3]);//采用上一帧
					}

					if (intensity == 0)// || intensity == 255))//结果表明 摄像头固定,有的点会一直错误
					{//上一帧也是错误点,且没修复,接着修复					
						inpaintDataMask[j] = (uchar)255;
						k4++;
					}
				}
				pRGBX->rgbRed = intensity;
				pRGBX->rgbGreen = intensity;
				pRGBX->rgbBlue = intensity;
				++pRGBX;
				++pBuffer;
			}
		}

	// std::cout << setw(5)<< k1 << setw(5) << k2  <<"为0点:"<<setw(5)<<k3<<"  修正:"<<setw(5)<<k4<<"  "<<" "<<std::endl ;
		//复制上一帧
	//	memcpy( m_pDepthRGBX_Last,m_pDepthRGBX, sizeof(RGBQUAD)*cDepthHeight*cDepthWidth);

		// Draw the data with OpenCV
		Mat DepthImage(nHeight, nWidth, CV_8UC4, m_pDepthRGBX);
		//imshow("orignal", DepthImage);
		//cvMoveWindow("orignal",0,0);
		Mat depthImageRGB;
		cvtColor(DepthImage,depthImageRGB,CV_RGBA2RGB);
		cv::inpaint(depthImageRGB, inpaintMask, inpaintResult, 3, CV_INPAINT_TELEA);// CV_INPAINT_NS);//空洞太大了效果不好
		//使用了inpaint后,就是第一帧会修复,其他的都不会修复了。
	//	imshow("inpaint", inpaintResult);
	//	cvMoveWindow("inpaint", 500, 0);

		//cvSmooth(&inpaintResult, &m_pDepthMat_Last);这是c格式的支持cvmat的,下面的才是c++的
	//	Mat  blurMat;
	//	blur(inpaintResult, blurMat, Size(3, 3), Point(-1, -1)); //Size( w,h ):
	//	imshow("blur", blurMat);
		//cvMoveWindow("blur",500,500);
	
		//2015-5-10 晚 ,修改为缩小版
		cv::resize(m_pDepthMat_Last, m_pDepthMat_Last_Resize, cv::Size(cDepthWidth_RESIZE, cDepthHeight_RESIZE));

		//对 fuliye版本 调整位置
		cv::GaussianBlur(inpaintResult, m_pDepthMat_Last, Size(3, 3), 0,0); //Size( w,h ):
	
	


	//	m_pDepthMat_Last = inpaintResult.clone();//保存上一帧 

	//	imshow("gaussianBlur", m_pDepthMat_Last);
		//cvMoveWindow("gaussianBlur",0,500);
	//	cvMoveWindow("gaussianBlur", 0, 0);
	//	cvWaitKey(1);

	//	cout << "m_pDepthMat_Last :" << m_pDepthMat_Last.channels();
	 	 Mat foreMat;//提取前景
	 	//m_pDepthBackProcess.process_Mog2(m_pDepthMat_Last, foreMat);
		// m_pDepthBackProcess.depthProcessBackGround(m_pDepthMat_Last, m_pDepthMat_LastMask);
	// 	 m_pDepthBackProcess.testManyMethod(m_pDepthMat_Last, foreMat);

		 m_pDepthBackProcess.depthProcessBackGround(m_pDepthMat_Last_Resize, m_pDepthMat_LastMask_Resize);


		 /*
		 测试分割 	 
		 ImageSegment iseg;
		 m_pTempshow=iseg.regiongrowthIndepth3(m_pDepthMat_Last, m_pDepthMat_LastMask);
*/
		/* if( (foreMat.rows !=0 )&& (foreMat.cols !=0))
		 {	
			 m_pDepthMat_LastMask = foreMat.clone();//保存前景的掩码
		 }*/
	 


	//	cout <<"通道数目"<< inpaintResult.channels();
	//	BaseImageTools::SaveDepthImageToAVI(inpaintResult, nWidth, nHeight, depthWriter);

	//	BaseImageTools::SaveDepthImageToAVI(inpaintResult, nWidth, nHeight, depthWriter2);

		//BaseImageTools::SaveDepthImageToAVI(DepthImage, nWidth, nHeight, depthWriter);
/*		Mat show = DepthImage.clone();
		imshow("DepthImage2", show);
		*/
	}
コード例 #3
0
bool ofxDepthImageSequence::loadSequence(string newSequenceDirectory){
    

	ofDirectory sequenceList(newSequenceDirectory);
	if(!sequenceList.exists()){
		ofLogError("ofxDepthImageSequence -- sequence directory " + newSequenceDirectory + " does not exist!");
		return false;
	}
    
	if(sequenceLoaded){
		images.clear();
		sequenceLoaded = false;
	}


	sequenceList.allowExt("png");
	int numFiles = sequenceList.listDir();
	if(numFiles == 0){
		ofLogError("ofxTLDepthImageSequence -- sequence directory " + newSequenceDirectory + " is empty!");
		return false;
	}
	

	bool checkedForTimestamp = false;
	unsigned long firstFrameTimeOffset = 0;
	for(int i = 0; i < numFiles; i++){
        //backwards compat...
		if(sequenceList.getName(i).find("poster") != string::npos){
			ofLogWarning("discarding poster frame " + sequenceList.getPath(i) );
			continue;
		}
		
		if(!checkedForTimestamp){
			framesHaveTimestamps = sequenceList.getName(i).find("millis") != string::npos;
			checkedForTimestamp = true;
			ofLogVerbose("Frames have timestamps? " + string((framesHaveTimestamps ? "yes!" : "no :(")) );
		}
		
		
		images.push_back( DepthImage() );
		DepthImage& img = images[images.size()-1];
		img.path = sequenceList.getPath(i);
		
		if(framesHaveTimestamps){
			vector<string> split = ofSplitString(sequenceList.getName(i), "_", true, true);
			for(int l = 0; l < split.size(); l++){
				if(split[l] == "millis"){
					img.timestamp = ofToInt(split[l+1]);
					if(i == 0){
						firstFrameTimeOffset = img.timestamp;
					}
					img.timestamp -= firstFrameTimeOffset;
				}
			}
		}

		images.push_back( img );
	}
	
	//currentFrame = -1;
    if(framesHaveTimestamps){
	    durationInMillis = images[images.size()-1].timestamp;
    }

	ofLogVerbose("sequence is loaded " + ofToString( images.size() ));
    sequenceDirectory = newSequenceDirectory;
    sequenceLoaded = true;
	setFrame(0);
    updatePixels();
//	startThread();
	return true;
}