久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Basler USB Camera字節緩沖區到圖像的轉換

Basler USB Camera byte buffer to image conversion(Basler USB Camera字節緩沖區到圖像的轉換)
本文介紹了Basler USB Camera字節緩沖區到圖像的轉換的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

我有 Basler acA3800 USB 相機.

 IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);//圖片抓取成功?如果(grabResult.GrabSucceeded){byte[] buffer = grabResult.PixelData as byte[];ImageWindow.DisplayImage(0, grabResult);pictureBox1.Image = ImageFromRawBgraArray(buffer,3840,2748,PixelFormat.Format8bppIndexed);MessageBox.Show(grabResult.PixelTypeValue.ToString());}

此代碼部分顯示圖像自身窗口.

我有捕獲圖像的像素數據.原始圖像很好,但是當我將其轉換為圖像時,它已損壞.這是我的轉換函數.

 public Image ImageFromRawBgraArray(byte[] arr, int width, int height, PixelFormat pixelFormat){var output = new Bitmap(width, height, pixelFormat);var rect = new Rectangle(0, 0, width, height);var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);//逐行復制var arrRowLength = 寬度 * Image.GetPixelFormatSize(output.PixelFormat)/8;var ptr = bmpData.Scan0;for (var i = 0; i <高度; i++){Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);ptr += bmpData.Stride;}輸出.UnlockBits(bmpData);返回輸出;}

我認為這與像素類型有關.我選擇了 PixelFormat.Format8bppIndexed 的像素格式.其他的不工作.

 MessageBox.Show(grabResult.PixelTypeValue.ToString());

這個消息框給了我像素類型.上面寫著BayerBG8".這是什么意思?我應該怎么做才能獲得清晰的圖像?

解決方案

你得到的奇怪顏色是因為 Format8bppIndexed 是調色板,你從不編輯調色板,這意味著它保留了默認生成的 Windows調色板.但在您的情況下,此調色板無關緊要,因為圖像 不是 8 位索引格式;需要對其進行處理以將其轉換為 RGB.

BayerBG8 的快速 google 找到了我介紹這些內容的一般處理方式,但 .

請注意,上面的去馬賽克方法非常基本,并且會顯示 許多預期的工件.有更先進的方法可以分析數據并根據圖像的拍攝方式獲得更準確的結果,但您可能需要進行大量研究才能弄清楚所有這些并自己實施.

這是我做的一個小測試,從 我在網上找到的經過拜耳過濾的圖像(第一張圖像),我將其轉換為 8 位數組(此處顯示為灰度;第二張圖像).如您所見,我自己的去馬賽克(第三張圖片)遠不如他們從中得到的校正版本(第四張圖片)準確,而且,值得注意的是,它小了一個像素,因此顯示為白色邊框.

(請注意,與上面的示例不同,此圖像以綠色像素開頭,這意味著必須調整解碼參數)

I have Basler acA3800 USB camera.

            IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);
            // Image grabbed successfully?
            if (grabResult.GrabSucceeded)
            {
                byte[] buffer = grabResult.PixelData as byte[];
                ImageWindow.DisplayImage(0, grabResult);

                pictureBox1.Image = ImageFromRawBgraArray(buffer,3840,2748,PixelFormat.Format8bppIndexed);
                MessageBox.Show(grabResult.PixelTypeValue.ToString());
            }

This code section shows image self window.

I have pixel data of captured image. Original image is good but when I convert it to Image, it corrupt. And here is my conversion function.

    public Image ImageFromRawBgraArray(byte[] arr, int width, int height, PixelFormat pixelFormat)
    {
        var output = new Bitmap(width, height, pixelFormat);
        var rect = new Rectangle(0, 0, width, height);
        var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);

        // Row-by-row copy
        var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8;
        var ptr = bmpData.Scan0;
        for (var i = 0; i < height; i++)
        {
            Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);
            ptr += bmpData.Stride;
        }

        output.UnlockBits(bmpData);
        return output;
    }

I think it is about pixel type. I have selected pixel format of PixelFormat.Format8bppIndexed. The others is not working.

                MessageBox.Show(grabResult.PixelTypeValue.ToString());

This messagebox gives me the pixeltype. and it says "BayerBG8". What does it mean? What should I do to get clear image?

解決方案

The odd colours you are getting are because Format8bppIndexed is paletted, and you never edit the palette, meaning it retains the default generated Windows palette. But in your case, this palette is irrelevant, because the image is not an 8-bit indexed format; it needs to be processed to convert it to RGB.

A quick google for BayerBG8 got me this page. The Bayer section there shows it's a rather peculiar transformation to use specifically patterned indices on the image as R, G and B.

Wikipedia has a whole article on how this stuff is generally processed, but this YouTube video shows the basics:

Note that this is a sliding window; for the first pixel, the colours are

R G
G B

but for the second pixel, they'll be

G R
B G

and for one row down, the first one will use

G B
R G

You'll end up with an image that is one pixel less wide and high than the given dimensions, since the last pixel on each row and all pixels on the last row won't have the neighbouring data needed to get their full pixel data. There are apparently more advanced algorithms to get around that, but for this method I'll just go over the basic sliding window method.

public static Byte[] BayerToRgb(Byte[] arr, ref Int32 width, ref Int32 height, ref Int32 stride, Boolean greenFirst, Boolean blueRowFirst)
{
    Int32 actualWidth = width - 1;
    Int32 actualHeight = height - 1;
    Int32 actualStride = actualWidth*3;
    Byte[] result = new Byte[actualStride*actualHeight];
    for (Int32 y = 0; y < actualHeight; y++)
    {
        Int32 curPtr = y*stride;
        Int32 resPtr = y*actualStride;
        Boolean blueRow = y % 2 == (blueRowFirst ? 0 : 1);
        for (Int32 x = 0; x < actualWidth; x++)
        {
            // Get correct colour components from sliding window
            Boolean isGreen = (x + y) % 2 == (greenFirst ? 0 : 1);
            Byte cornerCol1 = isGreen ? arr[curPtr + 1] : arr[curPtr];
            Byte cornerCol2 = isGreen ? arr[curPtr + stride] : arr[curPtr + stride + 1];
            Byte greenCol1 = isGreen ? arr[curPtr] : arr[curPtr + 1];
            Byte greenCol2 = isGreen ? arr[curPtr + stride + 1] : arr[curPtr + stride];
            Byte blueCol = blueRow ? cornerCol1 : cornerCol2;
            Byte redCol = blueRow ? cornerCol2 : cornerCol1;
            // 24bpp RGB is saved as [B, G, R].
            // Blue
            result[resPtr + 0] = blueCol;
            // Green
            result[resPtr + 1] = (Byte) ((greenCol1 + greenCol2)/2);
            // Red
            result[resPtr + 2] = redCol;
            curPtr++;
            resPtr+=3;
        }
    }
    height = actualHeight;
    width = actualWidth;
    stride = actualStride;
    return result;
}

The parameters greenFirst and blueRowFirst indicate whether green is the first encountered pixel on the image, and whether the blue pixels are on the first or second row. For your "BG" format, both of these should be false.

From the result of this, with the adjusted width, height and stride, you can convert that to a new image using the method you already used, but with Format24bppRgb as pixel format.

Personally I use a somewhat more advanced method that takes the input stride into account and can handle indexed content. If you're interested, that method can be found here.

Note that the demosaicing method above is very basic, and will show many of the expected artifacts. There are more advanced methods out there to analyse the data and get more accurate results based on how the image was taken, but it'll probably cost you quite some research to figure all that out and implement it yourself.

Here's a little test I did, starting from a Bayer-filtered image I found online (first image) which I converted to an 8-bit array (shown here as grayscale; second image). As you can see, my own demosaicing (third image) is far less accurate than the corrected version they got out of it (fourth image), and, notably, is one pixel smaller and thus shows a white border.

(Note that, unlike the examples above, this image starts with a green pixel, meaning the parameters to decode it had to be adjusted)

這篇關于Basler USB Camera字節緩沖區到圖像的轉換的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

ASP.NET Core authenticating with Azure Active Directory and persisting custom Claims across requests(ASP.NET Core 使用 Azure Active Directory 進行身份驗證并跨請求保留自定義聲明)
ASP.NET Core 2.0 Web API Azure Ad v2 Token Authorization not working(ASP.NET Core 2.0 Web API Azure Ad v2 令牌授權不起作用)
How do I get Azure AD OAuth2 Access Token and Refresh token for Daemon or Server to C# ASP.NET Web API(如何獲取守護進程或服務器到 C# ASP.NET Web API 的 Azure AD OAuth2 訪問令牌和刷新令牌) - IT屋-程序員軟件開發技
Azure KeyVault Active Directory AcquireTokenAsync timeout when called asynchronously(異步調用時 Azure KeyVault Active Directory AcquireTokenAsync 超時)
Getting access token using email address and app password from oauth2/token(使用電子郵件地址和應用程序密碼從 oauth2/token 獲取訪問令牌)
New Azure AD application doesn#39;t work until updated through management portal(新的 Azure AD 應用程序在通過管理門戶更新之前無法運行)
主站蜘蛛池模板: 国产亚洲精品精品国产亚洲综合 | 亚洲精品乱码久久久久久按摩观 | 亚洲激精日韩激精欧美精品 | 四虎最新地址 | 欧美日韩在线视频一区二区 | jav成人av免费播放 | 波多野结衣一区二区 | 久久精品久久久久久 | 久久人人爽人人爽人人片av免费 | 久久久久久久国产精品影院 | 久久精品视频网站 | 日本精品免费在线观看 | 99成人在线视频 | 一区中文 | 精品国产91久久久久久 | 亚洲精品久久久蜜桃 | 一级毛片在线播放 | 亚洲精品视频观看 | 99只有精品 | 网黄在线| 每日在线更新av | 婷婷开心激情综合五月天 | 99视频免费 | 日韩免费三级 | 天堂在线中文字幕 | 欧美日韩久久 | 日日草夜夜草 | 国产98色在线| 亚洲精品一区二区三区蜜桃久 | 欧美三区视频 | 欧美精品一区二区三区蜜桃视频 | 91免费福利在线 | 黄色一级大片在线免费看产 | 黄色一级大片在线免费看产 | 午夜电影福利 | 久久黄网| 亚洲第1页| 国产亚洲一区二区三区在线观看 | 99热视| 欧美日韩久久精品 | 午夜视频免费 |