簡體   English   中英

在c#中轉換圖像

[英]Converting Image in c#

編輯:已解決! 有關詳細信息,請參閱下面的答案。 我無法找到原始問題的答案,但我找到了另一種解決方案

這個問題可能會在其他地方被問到,但我一直在尋找幾天,找不到任何有用的東西。

問題:我需要一次性將“Stream”轉換為“image(bgr,byte)”,是否有一種方法/命令可以直接從System.Drawing.Image.FromStream轉換為Emgu.CV.Image(Bgr,Byte)沒有從流到 圖像轉換到位圖圖像(bgr,字節)

信息:我在Visual Studio 2010中使用c#進行編碼,這是我的論文項目的一部分。 我正在從網絡上的IP攝像機拍攝圖像流,並應用許多算法來檢測面部/提取面部特征並識別個人面部。 在我的筆記本電腦本地相機上我可以實現約25~(給或拿)的FPS,包括算法,因為我不需要轉換圖像。 對於IP攝像機流,我需要多次轉換才能達到所需的格式,結果大約為5-8fps。

(我知道我目前的方法是非常低效的,這就是為什么我在這里,我實際上是將圖像總共轉換5次(甚至是灰度縮放),實際上只使用了我處理器內存的一半(i7,8gb RAM))。 它必須是圖像(bgr,byte),因為這是算法將使用的唯一格式。

我用來獲取圖像的代碼:

//headers
using System.IO
using System.Threading;
using System.Net;
//request a connection
req = (HttpWebRequest)HttpWebRequest.Create(cameraUrl);
//gives chance for timeout for errors to occur or loss of connection
req.AllowWriteStreamBuffering = true;
req.Timeout = 20000;
//retrieve response (if successfull)
res = req.GetResponse();
//image returned
stream = res.GetResponseStream();

我在后台有很多東西管理連接,數據,安全等,我已經縮短到上面的代碼。 我目前的代碼將圖像轉換為所需的輸出:

//Convert stream to image then to bitmap
Bitmap bmpImage = new Bitmap(System.Drawing.Image.FromStream(stream));                    
//Convert to emgu image (desired goal)
currentFrame = new Emgu.CV.Image<Bgr, Byte>(bmpImage);
//gray scale for other uses
gray = currentFrame.Convert<Gray, Byte>();

我知道有一種方法可以暫時在本地保存圖像,但出於安全考慮,我需要避免這種情況。 我正在尋找更多直接轉換以幫助節省處理能力。 我忽略了什么嗎? 所有幫助表示贊賞。

謝謝閱讀。 (如果有人要求更多細節,我會更新)-Dave

你有一些潛在的瓶頸,其中最重要的是你可能將流解碼為圖像然后將其轉換為位圖然后轉換為openCV圖像。

解決此問題的一種方法是完全繞過.NET映像。 這將涉及嘗試直接使用libjpeg。 在C#中有一個自由端口,你可以在IIRC中掛鈎,在每個掃描線的基礎上調用它來填充緩沖區。

缺點是你在托管代碼中解碼JPEG數據的速度至少比C語言低1.5倍,盡管坦率地說我希望網絡速度相形見絀。

OpenCV應該能夠直接讀取jpeg圖像(想猜測它們在引擎蓋下使用的是什么?調查說:libjpeg),這意味着你可以緩沖整個流並將其交給OpenCV並完全繞過.NET層。

我相信我找到了問題的答案 我已經嘗試使用Vano Maisuradze的內存處理方法,它將fps提高了很小的幅度(沒有測試就不會立即顯着)。 還要感謝Plinths的回答,我對多線程有了解,我可以隨着我的進步優化這一點,因為我可以將算法拆分為並行工作。

我認為我的原因是網絡速度! 不是實際的算法延遲。 正如Vano用秒表指出的那樣,算法並沒有真正消耗那么多。 因此,無論使用和不使用算法,如果我使用線程進行優化,速度大致相同,那么下一幀將在前一幀完成處理時收集。

我對一些物理Cisco路由器進行了一些測試,如果速度慢一點,時鍾速度和帶寬變得明顯,我得到了相同的結果。 所以我需要找到一種方法來更快地檢索網絡上的幀,非常感謝所有回答誰幫助我更好理解的人!

結論:

  • 多線程優化
  • 在內存中處理而不是不斷轉換
  • 更好的網絡解決方案(更高的帶寬和速度

編輯:在內存中檢索圖像和進程的代碼,供尋找幫助的任何人使用

public void getFrames(object sender, EventArgs e)
{//Gets a frame from the IP cam
    //Replace "IPADDRESS", "USERNAME", "PASSWORD" 
    //with respective data for your camera
    string sourceURL = "http://IPADDRESS/snapshot.cgi?user=USERNAME&pwd=PASSWORD";
    //used to store the image retrieved in memory
    byte[] buffer = new byte[640 * 480];
    int read, total = 0;

    //Send a request to the peripheral via HTTP
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sourceURL);
    WebResponse resp = req.GetResponse();

    //Get the image capture after recieving a request
    //Note: just a screenshot not a steady stream
    Stream stream = resp.GetResponseStream();
    while ((read = stream.Read(buffer, total, 1000)) != 0)
    {
        total += read;
    }//While End

    //Convert memory (byte) to bitmap and store in a picturebox    
    pictureBox1.Image = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
}//getFrames End

private void button1_Click(object sender, EventArgs e)
{//Trigger an event to start running the function when possible
    Application.Idle += new EventHandler(getFrames);
}//Button1_Click End

您可以將多個圖像保存在內存(緩沖區)中,然后從緩沖區開始處理。

像這樣的東西:

//Convert stream to image then to bitmap
Bitmap bmpImage = new Bitmap(System.Drawing.Image.FromStream(stream));                    
//Convert to emgu image (desired goal)
currentFrame = new Emgu.CV.Image<Bgr, Byte>(bmpImage);

//gray scale for later use
gray = currentFrame.Convert<Gray, Byte>();
SaveToBuffer(gray);

Queue<Emgu.CV.Image<Gray, Byte>> buffer = new Queue<Emgu.CV.Image<Gray, Byte>>();
bool canProcess = false;

// ...

private void SaveToBuffer(Emgu.CV.Image<Gray, Byte> img)
{
    buffer.Enqueue(img);
    canProcess = buffer.Count > 100;
}

private void Process()
{
    if(canProcess)
    {
        buffer.Dequeue();
        // Processing logic goes here...
    }
    else
    {
        // Buffer is still loading...
    }
}

但請注意,您需要足夠的RAM來將圖像存儲在內存中,還應調整緩沖區大小以滿足您的要求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM