In old version of opencv we had the class like CvvImage, that were easily used for MFC controls to display camera images or simple images from the OpenCV. But in 2.4 or 2.3 this support is finished by the OpenCV , i wonder if we have any other class in new version.
在旧版本的opencv中,我们有CvvImage类,它很容易用于MFC控件以显示来自opencv的相机图像或简单图像。但是在2.4或2.3中,这个支持是OpenCV完成的,我想知道在新版本中是否还有其他类。
My application is MFC SDI and inside view i am over riding the OnPaint function. In previous opencv i was using Paint function like
我的应用程序是MFC SDI,我正在运行OnPaint函数。在之前的opencv中,我使用了Paint函数
void CRightCameraView::OnPaint()
{
CPaintDC dc(this); // device context for painting
m_CVvimageObj.CopyOf(m_iplImageFrame); //copy IplImage frame
if(m_bImageDisplay)
{
m_CVvimageObj.Show(dc.GetSafeHdc(),10,0,m_CVvimageObj.Width(),m_CVvimageObj.Height());
}
}
Kindly guide me which is the most update version of class to do same thing and support such DC controls of MFC.
请指导我哪个是类最更新的版本做同样的事情,并支持这样的MFC的DC控件。
3 个解决方案
#1
1
Since i could not find the answer i would like to help others what i did.
因为我找不到答案,我想帮助别人我所做的。
I have extracted cvvimage class manually and added in my project and then i did the following ..
我已经手工提取了cvvimage类并添加到我的项目中,然后我做了如下的事情。
in my views header file i declared
在我声明的视图头文件中
CvvImage m_CVvImageObj;
cv::Mat m_matImage;
inside my CPP file of view , i have called following in initialization function
在我的CPP视图中,我已经调用了初始化函数。
m_matImage = cv::imread(strA.GetBuffer(),CV_LOAD_IMAGE_COLOR); // Read the file
if(! m_matImage.data ) // Check for invalid input
{
AfxMessageBox(L"Could not open or find the image");
}
IplImage iplimg = m_matImage;
m_CVvImageObj.CopyOf(&iplimg);
UpdateData();
Invalidate();
inside the overided function of OnPaint inside view i added
在OnPaint的覆盖函数内部,我添加了视图
if(m_CVvImageObj.GetImage())
{
//m_CurrentFrame.Show
m_CVvImageObj.Show(dc.GetSafeHdc(),10,0,m_CVvImageObj.Width(),m_CVvImageObj.Height());
}
Cvvimage h file is the following
Cvvimage h文件如下所示
#pragma once
//#pragma once
#ifndef CVVIMAGE_CLASS_DEF
#define CVVIMAGE_CLASS_DEF
#include <opencv2\highgui\highgui.hpp>
class CvvImage
{
public:
CvvImage();
virtual ~CvvImage();
virtual bool Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
virtual bool Load( const char* filename, int desired_color = 1 );
virtual bool LoadRect( const char* filename,
int desired_color, CvRect r );
#if defined WIN32 || defined _WIN32
virtual bool LoadRect( const char* filename,int desired_color, RECT r )
{
return LoadRect( filename, desired_color,
cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
}
#endif
virtual bool Save( const char* filename );
virtual void CopyOf( CvvImage& image, int desired_color = -1 );
virtual void CopyOf( IplImage* img, int desired_color = -1 );
IplImage* GetImage() { return m_img; };
virtual void Destroy(void);
int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
virtual void Fill( int color );
virtual void Show( const char* window );
#if defined WIN32 || defined _WIN32
virtual void Show( HDC dc, int x, int y, int width, int height,
int from_x = 0, int from_y = 0 );
virtual void DrawToHDC( HDC hDCDst, RECT* pDstRect );
virtual void DrawToHDC( HDC hDCDst, CvRect pDstRect );
#endif
protected:
IplImage* m_img;
};
typedef CvvImage CImage;
#endif
and CPP file for cvvimage class is following
cvvimage类的CPP文件如下
///////////////////////////////////////////////////////////////////////////////////////////////////
//CvvImage.cpp
#include "StdAfx.h"
#include "CvvImage.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
CV_INLINE RECT NormalizeRect( RECT r );
CV_INLINE RECT NormalizeRect( RECT r )
{
int t;
if( r.left > r.right )
{
t = r.left;
r.left = r.right;
r.right = t;
}
if( r.top > r.bottom )
{
t = r.top;
r.top = r.bottom;
r.bottom = t;
}
return r;
}
CV_INLINE CvRect RectToCvRect( RECT sr );
CV_INLINE CvRect RectToCvRect( RECT sr )
{
sr = NormalizeRect( sr );
return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
}
CV_INLINE RECT CvRectToRect( CvRect sr );
CV_INLINE RECT CvRectToRect( CvRect sr )
{
RECT dr;
dr.left = sr.x;
dr.top = sr.y;
dr.right = sr.x + sr.width;
dr.bottom = sr.y + sr.height;
return dr;
}
CV_INLINE IplROI RectToROI( RECT r );
CV_INLINE IplROI RectToROI( RECT r )
{
IplROI roi;
r = NormalizeRect( r );
roi.xOffset = r.left;
roi.yOffset = r.top;
roi.width = r.right - r.left;
roi.height = r.bottom - r.top;
roi.coi = 0;
return roi;
}
void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
{
assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = origin ? abs(height) : -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short)bpp;
bmih->biCompression = BI_RGB;
if( bpp == 8 )
{
RGBQUAD* palette = bmi->bmiColors;
int i;
for( i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
CvvImage::CvvImage()
{
m_img = 0;
}
void CvvImage::Destroy()
{
cvReleaseImage( &m_img );
}
CvvImage::~CvvImage()
{
Destroy();
}
bool CvvImage::Create( int w, int h, int bpp, int origin )
{
const unsigned max_img_size = 10000;
if( (bpp != 8 && bpp != 24 && bpp != 32) ||
(unsigned)w >= max_img_size || (unsigned)h >= max_img_size ||
(origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
{
assert(0); // most probably, it is a programming error
return false;
}
if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
{
if( m_img && m_img->nSize == sizeof(IplImage))
Destroy();
m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
}
if( m_img )
m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
return m_img != 0;
}
void CvvImage::CopyOf( CvvImage& image, int desired_color )
{
IplImage* img = image.GetImage();
if( img )
{
CopyOf( img, desired_color );
}
}
#define HG_IS_IMAGE(img) \
((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && \
((IplImage*)img)->imageData != 0)
void CvvImage::CopyOf( IplImage* img, int desired_color )
{
if( HG_IS_IMAGE(img) )
{
int color = desired_color;
CvSize size = cvGetSize( img );
if( color < 0 )
color = img->nChannels > 1;
if( Create( size.width, size.height,
(!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
img->origin ))
{
cvConvertImage( img, m_img, 0 );
}
}
}
bool CvvImage::Load( const char* filename, int desired_color )
{
IplImage* img = cvLoadImage( filename, desired_color );
if( !img )
return false;
CopyOf( img, desired_color );
cvReleaseImage( &img );
return true;
}
bool CvvImage::LoadRect( const char* filename,
int desired_color, CvRect r )
{
if( r.width < 0 || r.height < 0 ) return false;
IplImage* img = cvLoadImage( filename, desired_color );
if( !img )
return false;
if( r.width == 0 || r.height == 0 )
{
r.width = img->width;
r.height = img->height;
r.x = r.y = 0;
}
if( r.x > img->width || r.y > img->height ||
r.x + r.width < 0 || r.y + r.height < 0 )
{
cvReleaseImage( &img );
return false;
}
if( r.x < 0 )
{
r.width += r.x;
r.x = 0;
}
if( r.y < 0 )
{
r.height += r.y;
r.y = 0;
}
if( r.x + r.width > img->width )
r.width = img->width - r.x;
if( r.y + r.height > img->height )
r.height = img->height - r.y;
cvSetImageROI( img, r );
CopyOf( img, desired_color );
cvReleaseImage( &img );
return true;
}
bool CvvImage::Save( const char* filename )
{
if( !m_img )
return false;
cvSaveImage( filename, m_img );
return true;
}
void CvvImage::Show( const char* window )
{
if( m_img )
cvShowImage( window, m_img );
}
void CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
{
if( m_img && m_img->depth == IPL_DEPTH_8U )
{
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
int bmp_w = m_img->width, bmp_h = m_img->height;
FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
SetDIBitsToDevice(
dc, x, y, sw, sh, from_x, from_y, from_y, sh,
m_img->imageData + from_y*m_img->widthStep,
bmi, DIB_RGB_COLORS );
}
}
void CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect )
{
if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
{
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
int bmp_w = m_img->width, bmp_h = m_img->height;
CvRect roi = cvGetImageROI( m_img );
CvRect dst = RectToCvRect( *pDstRect );
if( roi.width == dst.width && roi.height == dst.height )
{
Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
return;
}
if( roi.width > dst.width )
{
SetStretchBltMode(
hDCDst, // handle to device context
HALFTONE );
}
else
{
SetStretchBltMode(
hDCDst, // handle to device context
COLORONCOLOR );
}
FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
::StretchDIBits(hDCDst,dst.x, dst.y, dst.width, dst.height,roi.x, roi.y, roi.width, roi.height,\
m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
}
}
void CvvImage::DrawToHDC( HDC hDCDst, CvRect pDstRect )
{
RECT rDest=CvRectToRect(pDstRect);
DrawToHDC(hDCDst,&rDest);
}
void CvvImage::Fill( int color )
{
cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
}
enjoy.
享受。
#2
1
1.first load a picture get pic name and path.
1。首先载入图片获得图片名称和路径。
void CvlistDlg::OnBnClickedRead()
{
CString FilePathName;
CString FileName;
CFileDialog openVideo(true);
openVideo.m_ofn.lpstrTitle = _T("Open");
if (IDOK == openVideo.DoModal()){
FileName = openVideo.GetFileName();
FilePathName = openVideo.GetPathName();
_currentFile._fileName = FileName;
_currentFile._filePath = FilePathName;
}
}
2.add follow code in your button callback function.
2。在按钮回调函数中添加follow代码。
void CvlistDlg::OnBnClickedOk(){
cv::Mat img = cv::imread(str);
CDC *pDC = GetDlgItem(IDC_Pic)->GetDC();
HDC hDC = pDC->GetSafeHdc();
CRect rect;
GetDlgItem(IDC_Pic)->GetClientRect(&rect);
int rw = rect.right - rect.left; //the width of your picture control
int rh = rect.bottom - rect.top;
if (!img.data){
MessageBox(_T("read picture fail!"));
return;
}
cv::resize(img, img, cv::Size(rw, rh));
IplImage iplimg = img;
m_CVvImageObj.CopyOf(&iplimg);
UpdateData();
if (m_CVvImageObj.GetImage()){
m_CVvImageObj.Show(pDC->GetSafeHdc(), 0, 0, rw, rh);
}
}
I hope those can give you some help.
我希望他们能给你一些帮助。
#3
0
You don't need of IplImage. Basically you can draw a cv::Mat to a DC of a MFC control, using StretchDIBits. It accepts pointer to memory block where the bitmap is stored... in this case cv::Mat.data
你不需要IplImage。基本上,您可以使用担架将cv: Mat绘制到MFC控件的DC。它接受一个指向内存块的指针,在这个块中存储位图。在这种情况下简历::Mat.data
But remember that (this make me crazing before)
但是记住这一点(这让我很疯狂)
- GDI requires DWORD alignment while cv::Mat don't use any rows padding
- GDI需要DWORD对齐,而cv::Mat不使用任何行填充。
- In addition your Mat could be a ROI this means that at the end each rows there isn't next row but the image that continues
- 此外,您的Mat可能具有ROI,这意味着在每一行的末尾都没有下一行,只有继续运行的映像
You can have DWORD alignment in OpenCV using images where cols % 4 == 0 so you can add a border to your image
您可以在OpenCV中使用cols % 4 = 0的图像进行DWORD对齐,以便向映像添加边框
border = 4 - (img.cols % 4);
if ( (border<4 && border > 0) || img.isContinuous() == false)
{
cv::copyMakeBorder(img, tmpImg, 0, 0, 0, border, cv::BORDER_CONSTANT, 0);
}
else
tmpImg = img
Using copyMakeBorder you will solve both requirements
使用copyMakeBorder将解决这两个需求
Another issues is grey images because MFC requires a flat palette to display it. You can convert your Mat with cvtColor or create the palette:
另一个问题是灰色图像,因为MFC需要一个平面调色板来显示它。您可以转换您的席与cvtColor或创建调色板:
uchar buffer[sizeof(BITMAPINFO) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
bmih->biBitCount = 8*img.elemenSize()
bmih->biWidth = tmpImg.cols;
bmih->biHeight = -tmpImg.rows;// DIB are bottom ->top
bmih->...
//The palette is required for grey image
if (bmih->biBitCount == 8)
{
RGBQUAD* palette = bmi->bmiColors;
for (int i = 0; i < 256; i++)
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
finally draw to HDC
最后画HDC
imgH = img.rows;
imgW = img.cols; //use original cols to avoid border
ClientDC hDC(WinCtrl);
//rr is relative to control
RECT rr; WinCtrl->GetClientRect(&rr);
StretchDIBits(hDC,
0, 0, rr.right, rr.bottom,
0, 0, imgW, imgH,
tmpImg.data, bmi, DIB_RGB_COLORS, SRCCOPY);
You can find detailed info and a class to manage image fitting here: http://www.pklab.net/?&id=390&lang=EN&t=How-to-display-an-OpenCV-image-or-video-in-your-own-MFC-interface
您可以在这里找到详细的信息和管理图像匹配的类:http://www.pklab.net/?
#1
1
Since i could not find the answer i would like to help others what i did.
因为我找不到答案,我想帮助别人我所做的。
I have extracted cvvimage class manually and added in my project and then i did the following ..
我已经手工提取了cvvimage类并添加到我的项目中,然后我做了如下的事情。
in my views header file i declared
在我声明的视图头文件中
CvvImage m_CVvImageObj;
cv::Mat m_matImage;
inside my CPP file of view , i have called following in initialization function
在我的CPP视图中,我已经调用了初始化函数。
m_matImage = cv::imread(strA.GetBuffer(),CV_LOAD_IMAGE_COLOR); // Read the file
if(! m_matImage.data ) // Check for invalid input
{
AfxMessageBox(L"Could not open or find the image");
}
IplImage iplimg = m_matImage;
m_CVvImageObj.CopyOf(&iplimg);
UpdateData();
Invalidate();
inside the overided function of OnPaint inside view i added
在OnPaint的覆盖函数内部,我添加了视图
if(m_CVvImageObj.GetImage())
{
//m_CurrentFrame.Show
m_CVvImageObj.Show(dc.GetSafeHdc(),10,0,m_CVvImageObj.Width(),m_CVvImageObj.Height());
}
Cvvimage h file is the following
Cvvimage h文件如下所示
#pragma once
//#pragma once
#ifndef CVVIMAGE_CLASS_DEF
#define CVVIMAGE_CLASS_DEF
#include <opencv2\highgui\highgui.hpp>
class CvvImage
{
public:
CvvImage();
virtual ~CvvImage();
virtual bool Create( int width, int height, int bits_per_pixel, int image_origin = 0 );
virtual bool Load( const char* filename, int desired_color = 1 );
virtual bool LoadRect( const char* filename,
int desired_color, CvRect r );
#if defined WIN32 || defined _WIN32
virtual bool LoadRect( const char* filename,int desired_color, RECT r )
{
return LoadRect( filename, desired_color,
cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top ));
}
#endif
virtual bool Save( const char* filename );
virtual void CopyOf( CvvImage& image, int desired_color = -1 );
virtual void CopyOf( IplImage* img, int desired_color = -1 );
IplImage* GetImage() { return m_img; };
virtual void Destroy(void);
int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; };
int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;};
int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; };
virtual void Fill( int color );
virtual void Show( const char* window );
#if defined WIN32 || defined _WIN32
virtual void Show( HDC dc, int x, int y, int width, int height,
int from_x = 0, int from_y = 0 );
virtual void DrawToHDC( HDC hDCDst, RECT* pDstRect );
virtual void DrawToHDC( HDC hDCDst, CvRect pDstRect );
#endif
protected:
IplImage* m_img;
};
typedef CvvImage CImage;
#endif
and CPP file for cvvimage class is following
cvvimage类的CPP文件如下
///////////////////////////////////////////////////////////////////////////////////////////////////
//CvvImage.cpp
#include "StdAfx.h"
#include "CvvImage.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
CV_INLINE RECT NormalizeRect( RECT r );
CV_INLINE RECT NormalizeRect( RECT r )
{
int t;
if( r.left > r.right )
{
t = r.left;
r.left = r.right;
r.right = t;
}
if( r.top > r.bottom )
{
t = r.top;
r.top = r.bottom;
r.bottom = t;
}
return r;
}
CV_INLINE CvRect RectToCvRect( RECT sr );
CV_INLINE CvRect RectToCvRect( RECT sr )
{
sr = NormalizeRect( sr );
return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top );
}
CV_INLINE RECT CvRectToRect( CvRect sr );
CV_INLINE RECT CvRectToRect( CvRect sr )
{
RECT dr;
dr.left = sr.x;
dr.top = sr.y;
dr.right = sr.x + sr.width;
dr.bottom = sr.y + sr.height;
return dr;
}
CV_INLINE IplROI RectToROI( RECT r );
CV_INLINE IplROI RectToROI( RECT r )
{
IplROI roi;
r = NormalizeRect( r );
roi.xOffset = r.left;
roi.yOffset = r.top;
roi.width = r.right - r.left;
roi.height = r.bottom - r.top;
roi.coi = 0;
return roi;
}
void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
{
assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = origin ? abs(height) : -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short)bpp;
bmih->biCompression = BI_RGB;
if( bpp == 8 )
{
RGBQUAD* palette = bmi->bmiColors;
int i;
for( i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
CvvImage::CvvImage()
{
m_img = 0;
}
void CvvImage::Destroy()
{
cvReleaseImage( &m_img );
}
CvvImage::~CvvImage()
{
Destroy();
}
bool CvvImage::Create( int w, int h, int bpp, int origin )
{
const unsigned max_img_size = 10000;
if( (bpp != 8 && bpp != 24 && bpp != 32) ||
(unsigned)w >= max_img_size || (unsigned)h >= max_img_size ||
(origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
{
assert(0); // most probably, it is a programming error
return false;
}
if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h )
{
if( m_img && m_img->nSize == sizeof(IplImage))
Destroy();
m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 );
}
if( m_img )
m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
return m_img != 0;
}
void CvvImage::CopyOf( CvvImage& image, int desired_color )
{
IplImage* img = image.GetImage();
if( img )
{
CopyOf( img, desired_color );
}
}
#define HG_IS_IMAGE(img) \
((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && \
((IplImage*)img)->imageData != 0)
void CvvImage::CopyOf( IplImage* img, int desired_color )
{
if( HG_IS_IMAGE(img) )
{
int color = desired_color;
CvSize size = cvGetSize( img );
if( color < 0 )
color = img->nChannels > 1;
if( Create( size.width, size.height,
(!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8,
img->origin ))
{
cvConvertImage( img, m_img, 0 );
}
}
}
bool CvvImage::Load( const char* filename, int desired_color )
{
IplImage* img = cvLoadImage( filename, desired_color );
if( !img )
return false;
CopyOf( img, desired_color );
cvReleaseImage( &img );
return true;
}
bool CvvImage::LoadRect( const char* filename,
int desired_color, CvRect r )
{
if( r.width < 0 || r.height < 0 ) return false;
IplImage* img = cvLoadImage( filename, desired_color );
if( !img )
return false;
if( r.width == 0 || r.height == 0 )
{
r.width = img->width;
r.height = img->height;
r.x = r.y = 0;
}
if( r.x > img->width || r.y > img->height ||
r.x + r.width < 0 || r.y + r.height < 0 )
{
cvReleaseImage( &img );
return false;
}
if( r.x < 0 )
{
r.width += r.x;
r.x = 0;
}
if( r.y < 0 )
{
r.height += r.y;
r.y = 0;
}
if( r.x + r.width > img->width )
r.width = img->width - r.x;
if( r.y + r.height > img->height )
r.height = img->height - r.y;
cvSetImageROI( img, r );
CopyOf( img, desired_color );
cvReleaseImage( &img );
return true;
}
bool CvvImage::Save( const char* filename )
{
if( !m_img )
return false;
cvSaveImage( filename, m_img );
return true;
}
void CvvImage::Show( const char* window )
{
if( m_img )
cvShowImage( window, m_img );
}
void CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y )
{
if( m_img && m_img->depth == IPL_DEPTH_8U )
{
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
int bmp_w = m_img->width, bmp_h = m_img->height;
FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
SetDIBitsToDevice(
dc, x, y, sw, sh, from_x, from_y, from_y, sh,
m_img->imageData + from_y*m_img->widthStep,
bmi, DIB_RGB_COLORS );
}
}
void CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect )
{
if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData )
{
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
int bmp_w = m_img->width, bmp_h = m_img->height;
CvRect roi = cvGetImageROI( m_img );
CvRect dst = RectToCvRect( *pDstRect );
if( roi.width == dst.width && roi.height == dst.height )
{
Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
return;
}
if( roi.width > dst.width )
{
SetStretchBltMode(
hDCDst, // handle to device context
HALFTONE );
}
else
{
SetStretchBltMode(
hDCDst, // handle to device context
COLORONCOLOR );
}
FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin );
::StretchDIBits(hDCDst,dst.x, dst.y, dst.width, dst.height,roi.x, roi.y, roi.width, roi.height,\
m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
}
}
void CvvImage::DrawToHDC( HDC hDCDst, CvRect pDstRect )
{
RECT rDest=CvRectToRect(pDstRect);
DrawToHDC(hDCDst,&rDest);
}
void CvvImage::Fill( int color )
{
cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) );
}
enjoy.
享受。
#2
1
1.first load a picture get pic name and path.
1。首先载入图片获得图片名称和路径。
void CvlistDlg::OnBnClickedRead()
{
CString FilePathName;
CString FileName;
CFileDialog openVideo(true);
openVideo.m_ofn.lpstrTitle = _T("Open");
if (IDOK == openVideo.DoModal()){
FileName = openVideo.GetFileName();
FilePathName = openVideo.GetPathName();
_currentFile._fileName = FileName;
_currentFile._filePath = FilePathName;
}
}
2.add follow code in your button callback function.
2。在按钮回调函数中添加follow代码。
void CvlistDlg::OnBnClickedOk(){
cv::Mat img = cv::imread(str);
CDC *pDC = GetDlgItem(IDC_Pic)->GetDC();
HDC hDC = pDC->GetSafeHdc();
CRect rect;
GetDlgItem(IDC_Pic)->GetClientRect(&rect);
int rw = rect.right - rect.left; //the width of your picture control
int rh = rect.bottom - rect.top;
if (!img.data){
MessageBox(_T("read picture fail!"));
return;
}
cv::resize(img, img, cv::Size(rw, rh));
IplImage iplimg = img;
m_CVvImageObj.CopyOf(&iplimg);
UpdateData();
if (m_CVvImageObj.GetImage()){
m_CVvImageObj.Show(pDC->GetSafeHdc(), 0, 0, rw, rh);
}
}
I hope those can give you some help.
我希望他们能给你一些帮助。
#3
0
You don't need of IplImage. Basically you can draw a cv::Mat to a DC of a MFC control, using StretchDIBits. It accepts pointer to memory block where the bitmap is stored... in this case cv::Mat.data
你不需要IplImage。基本上,您可以使用担架将cv: Mat绘制到MFC控件的DC。它接受一个指向内存块的指针,在这个块中存储位图。在这种情况下简历::Mat.data
But remember that (this make me crazing before)
但是记住这一点(这让我很疯狂)
- GDI requires DWORD alignment while cv::Mat don't use any rows padding
- GDI需要DWORD对齐,而cv::Mat不使用任何行填充。
- In addition your Mat could be a ROI this means that at the end each rows there isn't next row but the image that continues
- 此外,您的Mat可能具有ROI,这意味着在每一行的末尾都没有下一行,只有继续运行的映像
You can have DWORD alignment in OpenCV using images where cols % 4 == 0 so you can add a border to your image
您可以在OpenCV中使用cols % 4 = 0的图像进行DWORD对齐,以便向映像添加边框
border = 4 - (img.cols % 4);
if ( (border<4 && border > 0) || img.isContinuous() == false)
{
cv::copyMakeBorder(img, tmpImg, 0, 0, 0, border, cv::BORDER_CONSTANT, 0);
}
else
tmpImg = img
Using copyMakeBorder you will solve both requirements
使用copyMakeBorder将解决这两个需求
Another issues is grey images because MFC requires a flat palette to display it. You can convert your Mat with cvtColor or create the palette:
另一个问题是灰色图像,因为MFC需要一个平面调色板来显示它。您可以转换您的席与cvtColor或创建调色板:
uchar buffer[sizeof(BITMAPINFO) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
bmih->biBitCount = 8*img.elemenSize()
bmih->biWidth = tmpImg.cols;
bmih->biHeight = -tmpImg.rows;// DIB are bottom ->top
bmih->...
//The palette is required for grey image
if (bmih->biBitCount == 8)
{
RGBQUAD* palette = bmi->bmiColors;
for (int i = 0; i < 256; i++)
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
finally draw to HDC
最后画HDC
imgH = img.rows;
imgW = img.cols; //use original cols to avoid border
ClientDC hDC(WinCtrl);
//rr is relative to control
RECT rr; WinCtrl->GetClientRect(&rr);
StretchDIBits(hDC,
0, 0, rr.right, rr.bottom,
0, 0, imgW, imgH,
tmpImg.data, bmi, DIB_RGB_COLORS, SRCCOPY);
You can find detailed info and a class to manage image fitting here: http://www.pklab.net/?&id=390&lang=EN&t=How-to-display-an-OpenCV-image-or-video-in-your-own-MFC-interface
您可以在这里找到详细的信息和管理图像匹配的类:http://www.pklab.net/?