unity 3 dとopencvのリアルタイム画像伝達,処理,効率的な解決策は,fpsにほとんど影響しない.


前回ブログでunityとopencvが画像を伝える問題があったので、やっと時間を見つけて解決しました.過程は1本の心の酸っぱい1本の涙で、unityにc++dllの同志を包んだことがあってきっとその中の苦痛を理解することができて、ネット上で多くの文章を見て、すべて大まかな言い方だけで、特に具体的な解決策がなくて、甚だしきに至っては多くの解決策はとても無責任で、すぐにメモリがあふれて、漏れて、境界を越えます.もちろん、人が1枚の画像しか伝えていないかもしれませんが、こんなにリアルタイム性はありません.还有unityとopencvのピクチャーの対照は本当に穴の上で穴をプラスして、具体的にどれだけ穴があって、誰が踏んで誰が知っていて、手動で滑稽でbbがなくて、コードをつけます
まずunity声明を見て
landeet,関数は具体的な道路識別,データ処理の関数である
setcolor、処理後の画像の色を設定して、できるだけこの関数を使わないでください、私はまだ測ったことがなくて、本当に時間がありません
flip、ピクチャ反転関数、opencv上のもので、この関数を使った理由は前のブログでも述べましたが、それを再カプセル化したのは高速処理のためです.
CreatImageは、指定されたメモリに画像を処理し、どのくらいのメモリを処理するかを決定し、画像のチャネル数を決定します.
    [DllImport("LaneIdentificationImg")]
    extern static int lanedet();
    [DllImport("LaneIdentificationImg")]
    extern static int SetColor(int[] col);
    [DllImport("LaneIdentificationImg")]
    extern static int Flip(int flip);
    [DllImport("LaneIdentificationImg")]
    extern static int CreatImage(IntPtr data, int Width, int Height, int Aisle);

Unityの操作.
メインスレッドに影響を与えないため、協程でしか実行できません.私のプロジェクトはまだ大きいです.最適化した後、画像を処理するシーンはありません.60以上のfpsがあります.画像処理をfiexdupdateに置いて、40 fpsぐらいしか走ることができません.携程に置いてもほとんど影響はありません.シーンの実行速度は60ぐらいです.同時にuiに表示される画像も非常にスムーズで、特に明らかなカートンはありません.
WritePNGToLocadが画像をローカルに生成するかどうか.ifの中のコードのブロックを削除することができることを使いたくなくて、何の役にも立たないでまた進度を遅らせて、このマクロを宣言しないことを提案します
    IEnumerator OutputRt()
    {

        while (true)
        {
            rt = camera.targetTexture;
            RenderTexture.active = rt;
            png.ReadPixels(new Rect(0, 0, imgsize.x, imgsize.y), 0, 0);
            yield return new WaitForSeconds(0.01f);//              
#if WritePNGToLocad
        byte[] dataBytes = png.EncodeToPNG();
#else
            pixels = png.GetPixels32();//          
            pixelHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
            pixelPointer = pixelHandle.AddrOfPinnedObject();//              GC      ,
#endif
            yield return new WaitForSeconds(0.01f);
            CreatImage(pixelPointer, (int)imgsize.x, (int)imgsize.y, 4);//      opencv   dll    
            yield return new WaitForSeconds(0.01f);
            Flip(0);//dll    
            yield return new WaitForSeconds(0.01f);
            float mark = lanedet();//dll    
            //---------      ,        --------
            mark /= 100;
            //LKAState = Mathf.Lerp(LKAState, mark, 0.05f);
            LKAState = mark;
            //---------------------------------------------
            yield return new WaitForSeconds(0.01f);
            Flip(0);//dll       
            cppixels = pixels;//      
            yield return new WaitForSeconds(0.01f);
            showpng.SetPixels32(cppixels);//                
            showpng.Apply();//    ,              
            yield return new WaitForSeconds(0.01f);
            pixelHandle.Free();//      

#if WritePNGToLocad
        string strSaveFile = "D:\\hehe" + ".png";
        FileStream fs = File.Open(strSaveFile, FileMode.OpenOrCreate);
        fs.Write(dataBytes, 0, dataBytes.Length);
        fs.Flush();
        fs.Close();
        png = null;
#endif
            RenderTexture.active = null;
        }
    }

Opencvの宣言
何も言うことはありません.上の声明と対照的です.
extern "C"  __declspec(dllexport) int lanedet();
extern "C"  __declspec(dllexport) int SetColor(int col[]);
extern "C"  __declspec(dllexport) BYTE * Flip(int flip);
extern "C"  __declspec(dllexport) int CreatImage(BYTE * data, int Width, int Height, int Aisle);

Opencv処理関数
何も言わないでまず通路を照らし合わせて、それから私にどうして4通路しか使えないのかと聞かないで、どうしてrgb 24はだめです
前編のブログのコードはこれに従って変更すればOKです.
static cv::Mat frame;//(900, 1440, CV_8UC4);
int CreatImage(BYTE * data,int Width,int Height ,int Aisle)
{
	using namespace cv;
	switch (Aisle)
	{
	case 1:
		frame = Mat(Height, Width, CV_8UC1);
		break;
	case 3:
		frame = Mat(Height, Width, CV_8UC3);
		break;
	case 4:
		frame = Mat(Height, Width, CV_8UC4);
		break;
	default:
		break;
	}
	BYTE * mark = data;//      
	//strcpy_s((char *)frame.data, Height*Width*Aisle+1, (char *)mark);//         ,    ,       , 
	frame.data = data;//       ,                             
	cv::cvtColor(frame, frame, cv::COLOR_RGBA2GRAY, Aisle);//      
	cv::cvtColor(frame, frame, cv::COLOR_GRAY2RGBA, Aisle);//     ,               。     ,      
	for (size_t i = 0; i < Height*Width*Aisle + 1; i++)
	{
		mark[i] = frame.data[i];
	}
    //for           
	//strcpy_s((char *)mark, Height*Width*Aisle + 1, (char *)frame.data);
	//*mark = *frame.data;
	//delete frame.data;
	frame.data = mark;
	return 1;
}
BYTE * Flip(int flip){
	cv::flip(frame, frame,flip);
	return frame.data;
}
int SetColor(int col[]){
	for (size_t i = 0; i < 6; i++)
	{
		color[i] = col[6];
	}
	return 1;
}