secile / UsbCamera

C# source code for using usb camera and web camera in WinForms/WPF. With only single CSharp source code. No external library required.
MIT License
179 stars 55 forks source link

Inconsistent Image Quality When Saving Still Capture Monochrome Sensor Data as BMP #31

Open SankarGaneshKumar opened 8 months ago

SankarGaneshKumar commented 8 months ago

We are experiencing a discrepancy in the image quality when saving Still capture from a monochrome sensor as an 8-bit BMP file. The output image does not match the expected quality and format, differing significantly from a reference BMP image known to be of high quality.

secile commented 8 months ago

Hello, thank you for your information. I have never used monochrome sensor.

  1. What product are you using? please send product url, if possible.
  2. you said 'Still capture' is discrepancy. Is it means image from GetBitmap() is good, and image from StillImageCaptured is no good?
  3. Which do you use WinForms, or WPF?
  4. Send me the image if possible.
  5. Let me know dump of VideoFormat. To get dump, execute as follows.
// get video format.
var cameraIndex = 0;
var formats = UsbCamera.GetVideoFormat(cameraIndex);

// select the format you want.
foreach (var item in formats) Console.WriteLine(item);
SankarGaneshKumar commented 8 months ago

Thank you for your prompt response.

  1. I have attached a zip file containing all the details you requested. It includes the datasheet for the cameras we are currently using.
  2. Both the Still Capture and GetBitmap() functions yield the same quality, which is lower compared to the reference image taken from the camera manufacturer's app. We attempted to save the images in various formats such as .png, .bmp, and .tif. However, the size of the image increases without a corresponding improvement in quality.
  3. Our application utilizes WinForms.

4 & 5. Please find the relevant information in the attachments.

Note: When attempting to obtain the video feed using your code, we initially encountered an error stating that it was unable to create a filter. To address this, I commented out the code as shown below (1st way):

// To show the preview, there are 3 ways. // 1. Use SetPreviewControl. (Works smoothly, recommended.) camera.SetPreviewControl(pictureBox1.Handle, pictureBox1.ClientSize); pictureBox1.Resize += (s, ev) => camera.SetPreviewSize(pictureBox1.ClientSize);

we are using this // 2. Use Timer and GetBitmap(). / var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this }; timer.Elapsed += (s, ev) => pictureBox1.Image = camera.GetBitmap(); timer.Start(); this.FormClosing += (s, ev) => timer.Stop(); /

Data.zip

secile commented 8 months ago

Could you send me 2 more information.

(6) When you create UsbCamera instance, which video format are you use? In case the code below, I selected formats[0].

// get video format.
var cameraIndex = 0;
var formats = UsbCamera.GetVideoFormat(cameraIndex);

// select the format you want.
foreach (var item in formats) Console.WriteLine(item);
var format = formats[0]; // <- selected format[0].

// create instance.
var camera = new UsbCamera(cameraIndex, format);

(7) What is a value of bBitCount of bitmap header member about line 446. image

SankarGaneshKumar commented 8 months ago

Hi,

For 6) we are using 55 CUG Camera , videoFormat[3]

Format: [Video], 20203859-0000-0010-8000-00aa00389b71, {Width=2592, Height=1944}, 333333, [VideoInfo2], Guid=f72a76a0-eb0a-11d0-ace4-0000c0cc16ba, VideoStandard=0, InputSize={2592, 1944}, MinCroppingSize={2592, 1944}, MaxCroppingSize={2592, 1944}, CropGranularityX=1, CropGranularityY=1, CropAlignX=1, CropAlignY=1, MinOutputSize={2592, 1944}, MaxOutputSize={2592, 1944}, OutputGranularityX=1, OutputGranularityY=1, StretchTapsX=0, StretchTapsY=0, ShrinkTapsX=0, ShrinkTapsY=0, MinFrameInterval=333333, MaxFrameInterval=333333, MinBitsPerSecond=1209323520, MaxBitsPerSecond=1209323520,

For 7th question share the above screenshot VideoFormats.txt 7

secile commented 7 months ago

At first I thought it was because of biBitCount was 8. The BmpBuilder.BufferToBitmap function does not work correctly if the buffer has 8 bits. But this time it wasn't the cause.

Now you are using videoFormat[3]. Please try to use another VideoFormat, especially, could you use VideoFormat that's format is VideoInfo instead of VideoInfo2.

SankarGaneshKumar commented 7 months ago

Tried both VideoInfo and VideoInfo2, but both are giving same quality. Attached the saved images for reference and here is the code which saves the still capture image

`try { // Check if a frame was previously captured if (bmp != null) { Image img = (Image)bmp; // Save the frame to a file

                Image image2 = Image.FromHbitmap(bmp.GetHbitmap());
                image2.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg;
                // Display a message or perform any desired action
                //  MessageBox.Show("Frame captured and saved!");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Camera Snapsot exception : " + DeviceName + ":" + ex.Message);
        }`

Do you think the code which is saving still capture is causing the issue?

Using_VideoInfo

Using Video info 2

secile commented 7 months ago

Do you think the code which is saving still capture is causing the issue?

StillImageCapture works fine in my environment.

The GetBitmap function and StillImageCapture call the same function. If GetBitmap is working fine, I think it is unlikely that StillImageCapture will work not fine.

One possibility, I want to confirm. As to 'Reference_Image.bmp' and 'Using_Still_Pin Capture.jpg' files you sent me, 'Reference_Image.bmp' is bitmap file, that is not compressed, and 'Using_Still_Pin Capture.jpg' is jpg file, that is compressed. 'Using_Still_Pin Capture.jpg' may have been compressed and degraded. Could you save 'Using_Still_Pin Capture' to bitmap, and compare with 'Reference_Image.bmp'?

To save bitmap instance to file, please see code below. I think you do not need to convert Bitmap to Image.

camera.StillImageCaptured += bmp =>
{
    bmp.Save(path, System.Drawing.Imaging.ImageFormat.Bmp);
};
rajeshamudala commented 2 months ago

Thanks for the response , we used the above code but still we are having quality issues , I am attaching image where left is reference image and right is the image we got from above code , Still i feel the left image have more quality image

Issue #2 We are using 2 camera's two camera's are running at different resolutions one is 1600 x 1300 & another one is 2592 x 1944 . If we are doing still capture ,The camera with 2592 x 1944 is giving image with same resolution but 1600 x1300 camera is giving still capture of 640 x 480 though while streaming it was at 1600 x 1300