PDA

View Full Version : Hello? McFly?



BenignVanilla
October 3, 2003, 21:32:31
I've sent a series of emails to the support desk, and posted here in this forum over the past couple of days, and I have heard nothing back.

Are these forums still active?
Is the support desk there?

BV.

BenignVanilla
October 3, 2003, 21:41:06
I just spoke with tech. support, and it turns out that support for this control is handled by the German office, which is on holiday today. This would explain the delay in response.

Stefan Geissler
October 6, 2003, 12:34:53
Hello,

Here comes a sample code for a simple image deinterlacing. The trick is to copy the even lines of a frame to a buffer first at the even and the next odd line Then the buffer is displayed in the video window. In the next step the odd lines are copied to the odd and next even line of the buffer and the buffer is displayed again. This results in two times display of the same frame, that is delivered from the frame grabber. Because of the double use of SetDIBitsToDevice(), the video seems to flicker at fast movements. In this case, only the even or the odd field should be copied and displayed.

The algorithm is implemented in a class named CListener. This class is inherited from CGrabberListener.

The header of Clistener looks as follows:


class CListener : public GrabberListener
{
public:
void SetViewCWnd( CWnd *pView);
CListener();
virtual ~CListener();
virtual void deviceLost( Grabber& param);
void SetParent(CWnd* pParent);
virtual void frameReady( Grabber& param, smart_ptr<MemBuffer> pBuffer, DWORD FrameNumber);

protected:
CWnd* m_pParent;
CWnd* m_pDrawCWnd;
void DrawBuffer( smart_ptr<MemBuffer> pBuffer);
void DoDeInterlace( smart_ptr<MemBuffer> pBuffer);
HBITMAP m_hbmBuffer; // Bitmap of the resulting image
CDC m_cBufferDC; // DC for the buffer bitmap
BYTE* m_pData; // pointer to the image data of the buffer image.

};


The deinterlacing is done as follows:


//////////////////////////////////////////////////////////////////////////
/*! Here do the DeInterlace
*/
void CListener::DoDeInterlace( smart_ptr<MemBuffer> pBuffer)
{
smart_ptr<BITMAPINFOHEADER> pInf = pBuffer->getBitmapInfoHeader();
int iBpP = pInf->biBitCount / 8; // Bytes per Pixel
BYTE *pBuf = pBuffer->getPtr(); // Pointer to the image data of the source image
int ibWidth = pInf->biWidth*iBpP; // Width in bytes of a scanline.
int iLine, iPos;

if( m_hbmBuffer == NULL)
{
// Create the buffer bitmap, if not already done.
BITMAPINFO bi;
ZeroMemory(&bi,sizeof( BITMAPINFO));
memcpy( &bi.bmiHeader, pInf.get(), sizeof(BITMAPINFOHEADER ));
bi.bmiHeader.biHeight = pInf->biWidth;
bi.bmiHeader.biWidth = pInf->biHeight;


m_hbmBuffer = CreateDIBSection(m_cBufferDC, &bi, DIB_RGB_COLORS,(void**)&m_pData,NULL,0);
}

// This is a simple and fast way. It copies the even source scan lines to the even
// and odd line of the destination bitmap.
for( iLine = 0; iLine < pInf->biHeight; iLine += 2)
{
iPos = iLine*ibWidth;
// copy even line to the even line in the buffer bitmap
memcpy( &(m_pData[iPos]), &(pBuf[iPos]), ibWidth);

// copy odd line to the even line in the buffer bitmap
memcpy( &(m_pData[(iLine+1)*ibWidth]), &(pBuf[iPos]), ibWidth);
}

DrawBuffer( pBuffer);
Sleep(5); // Sleep some milliseconds to slow down the frame rate between odd and even
// image.

// Now draw the second field
for( iLine = 1; iLine < pInf->biHeight-1; iLine += 2)
{
iPos = iLine*ibWidth;
// copy even line to the even line in the buffer bitmap
memcpy( &(m_pData[iPos]), &(pBuf[iPos]), ibWidth);

// copy odd line to the even line in the buffer bitmap
memcpy( &(m_pData[(iLine+1)*ibWidth]), &(pBuf[iPos]), ibWidth);
}
DrawBuffer( pBuffer);

}

The display of the image buffer is done as follows:
//////////////////////////////////////////////////////////////////////////
/*! Draw the image buffer into the DrawCWnd.
*/
void CListener::DrawBuffer( smart_ptr<MemBuffer> pBuffer)
{
if( m_pDrawCWnd != NULL)
{
if( pBuffer != 0 )
{
CDC *pDC = m_pDrawCWnd->GetDC();

smart_ptr<BITMAPINFOHEADER> pInf = pBuffer->getBitmapInfoHeader();

void* pBuf = pBuffer->getPtr();

int nLines = SetDIBitsToDevice(
pDC->GetSafeHdc(),// Handle to the device
0,
0,
pInf->biWidth, // Source rectangle width
pInf->biHeight, // Source rectangle height
0, // X-coordinate of lower-left corner of the source rect
0, // Y-coordinate of lower-left corner of the source rect
0, // First scan line in array
pInf->biHeight, // Number of scan lines
m_pData, // Modified address of array with DIB bits
reinterpret_cast<LPBITMAPINFO>( &*pInf ), // Address of structure with bitmap info
DIB_RGB_COLORS // RGB or palette indices
);
m_pDrawCWnd->ReleaseDC(pDC);
}
}
}


A complete C++ sample is attached to this entry

BenignVanilla
October 6, 2003, 15:52:21
Stephan,

Thanks so much. I'll check that out today. The flicker should not be an issue for us, as we want to snap stills from the video.

Any chance of a VB example?

BV.

Stefan Geissler
October 6, 2003, 16:02:16
A Visual Basic sample would be near similar, but this would be very slow, so live image display would be like a dia show.

Stefan Geissler
October 6, 2003, 16:41:10
Hello,

If you want to deinterlace only one frame per software, you should take the even field only. The Visual Basic function for interpolated deinterlacing looks like follows:



Private Sub cmdStart_Click()
Dim ImageData As Variant
Dim x As Integer, y As Integer

ICImagingControl1.LiveStop
'ICImagingControl1.MemorySnapImage
ImageData = ICImagingControl1.MemoryGetImageData
' Take the even fields only
For y = 0 To ICImagingControl1.ImageHeight - 3 Step 2
For x = 0 To 3 * ICImagingControl1.ImageWidth - 1
ImageData(x, y + 1) = (ImageData(x, y) + ImageData(x, y + 2)) / 2
Next x
Next y
ICImagingControl1.MemoryReleaseImageData ImageData
ICImagingControl1.Display
ICImagingControl1.MemorySaveImage "Test.bmp"
End Sub


In this function, the live video is stopped. The last captured frame, that has been automatically snapped to memory, is used for deinterlacing. After deinterlacing, the image is saved to a bmp file.
A complete Visual Basic project is attached to this entry. In this project, the deinterlacing is done during the live video is shown. Most of the frames are dropped, because the deinterlacing takes too much time.

( This thread is the same as the de-interlace thread.)

BenignVanilla
October 6, 2003, 22:40:10
The de-interlacing example code you posted in the first reply is perfect. That is what I needed. Thanks for the follow-up.

The images are nice, not perfect, but I expect that is a function of taking an image from a video feed.

This should meet our needs. Not I just need to bang over to the thread about saving as JPG, if we can do that. We're all set with this control.

BV.

Stefan Geissler
October 7, 2003, 08:05:21
Just send an email to support@eu.theimagingsource.com and i can send you the DLL for saving JPEG files.

Stefan Geissler
October 7, 2003, 09:00:34
Hello,

The deinterlaced image can be saved as JPEG image, if the JPEG.DLL is used. First of all, two necessary functions must be declared:
The saving function:


Private Declare Function DIBtoJPEG Lib "jpeg.dll" _
(ByVal name As String, _
ByVal Quality As Integer, _
ByVal Dib As Long) As Long


The function to free memory:


Private Declare Function GlobalFree Lib "kernel32" _
(ByVal hMem As Long) As Long


The deinterlacing function looks like follows:


Private Sub cmdStart_Click()
Dim ImageData As Variant
Dim x As Integer, y As Integer
Dim DIBPointer As Long ' Pointer to the DIB

ICImagingControl1.LiveStop
'ICImagingControl1.MemorySnapImage
ImageData = ICImagingControl1.MemoryGetImageData
' Take the even fields only
For y = 0 To ICImagingControl1.ImageHeight - 3 Step 2
For x = 0 To 3 * ICImagingControl1.ImageWidth - 1
ImageData(x, y + 1) = (ImageData(x, y) + ImageData(x, y + 2)) / 2
Next x
Next y
ICImagingControl1.MemoryReleaseImageData ImageData
ICImagingControl1.Display
' Save as bitmap
ICImagingControl1.MemorySaveImage "Test.bmp"

' Get the pointer to the DIB in the memory
DIBPointer = ICImagingControl1.MemoryGetDib
' Save the DIB as JPEG image
DIBtoJPEG "test.jpg", 80, DIBPointer
'Free the memory of the DIB. This is VERY important.
GlobalFree DIBPointer
End Sub


The JPEG.DLL must reside in the working or in the Windows\system32 directory, otherwise it will not be found by the application. A complete project saving deinterlaced JPEG images is attached to this post. This includes also the JPEG.DLL