基于Dialog的MFC对话框上利用OpenCV 3.0显示图片

原创 2015年07月09日 18:29:31


1. 操作准备

A.Win 7 x64 旗舰版

B.VS 2012 旗舰版

C.OpenCV 3.0.0

http://www.cnblogs.com/Romi/archive/2012/05/07/2487652.html

http://blog.csdn.net/fangpian/article/details/6233310

注:  

a.此处不累赘描述OpenCV 3.0在VS 2012上的部署过程。

b.此处依然使用网上流传的CvvImage在MFC 的Picture Control上进行图像显示。

c.末尾附带CvvImage.h和CvvImage.cpp代码。

d.此处尚未实现图片自适应显示。

2. 步骤

A)新建一个名为pictest的MFC项目。选择基于对话框,在静态库中使用MFC,不使用Unicode库。

图2-A-1

图2-A-2

B)在对话框中插入一个按钮和一个图片控件,并修改好对应ID。

图2-B-1

图2-B-2

C)在对话框头文件和源文件中分别加入CvvImage.h和CvvImage.cpp。

这两个文件我都放在项目目录下。

图2-C-1

在对话框头文件中加入头文件。

图2-C-2

D)初始化一些变量,并获取图片空间的句柄,以便于进行图像输出操作。

    在对话框的头文件添加:

    CRectrect;

    CStatic*pStc;//标识Picture Control

    CDC*pDC;

    HDChDC;

图2-D-1

    在对话框的构造函数出添加:

//初始化指针变量

    pStc= NULL;

    pDC= NULL;

图2-D-2

    在对话框的初始化函数OnInitDialog处添加:

pStc =(CStatic *)GetDlgItem(IDC_S_ShowImg);//标识所标记的控制窗口句柄

    pStc->GetClientRect(&rect);//获取并传递坐标

    pDC= pStc->GetDC();//获取设备上下文

    hDC= pDC->GetSafeHdc();//获取设备上下文的句柄

图2-D-3

E)为按钮添加处理函数,并添加:

    IplImage*img = cvLoadImage("1.jpg",1);//载入图片

    CvvImagecvimg;

    cvimg.CopyOf(img);

    cvimg.DrawToHDC(hDC,&rect);//显示在图片控件上

    ReleaseDC(pDC);//释放pDC的内存

图2-E-1

F)在项目目录下添加一张名为“1.jpg”的图片,Debug后可以显示。

图2-F-1

 

 

 

                                                           

3. 附

3.1     CvvImage.h

//**********************CvvImage.h**********************//

#pragma once

#ifndef CVVIMAGE_CLASS_DEF

#define CVVIMAGE_CLASS_DEF

#include"opencv2/highgui/highgui.hpp"

#include"opencv2/core/core.hpp"

#include"opencv2/imgproc/imgproc.hpp"

#include"opencv2/imgproc/imgproc_c.h"

 

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 );

#endif

protected:

 IplImage* m_img;

};

typedef CvvImage CImage;

#endif

3.2     CvvImage.cpp

//**********************CvvImage.cpp**********************//

#include "StdAfx.h"

#include "CvvImage.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

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, intorigin )

{

 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 && ((constIplImage*)(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 ) returnfalse;

 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, intfrom_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 todevice context

   HALFTONE );

 }

 else

 {

  SetStretchBltMode(

   hDCDst,           // handle todevice 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::Fill( int color )

{

 cvSet( m_img,cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255));

}

相关文章推荐

MFC中调用opencv里摄像头的实例

用是vs2013新建一个空的 mfc项目,配置该项目的属性。让该项目可以调用opencv的库以及相关函数。 //CMFCApplication12345Dlg  这个是主类名 void CMFCA...
  • teleger
  • teleger
  • 2017年02月05日 15:38
  • 799

利用MFC和OpenCV构建GUI程序读取摄像头视频

一、新建一个基于对话框的MFC应用程序,命名为opencv_mfc。        1、取消勾选“使用Unicode库”,勾选“在静态库中使用MFC”,取消勾选“关于”框,取消勾选“ActiveX控件...

MFC中使用OpenCV显示图像

文章内容 介绍在MFC对话框里使用Picture控件来显示和处理图像。

mfc使用opencv3.1

MFC配置opencv3.1.0的方法: 需要注意的一小点是,opencv3.1.0的平台集是vc12和vc14的并且下载里面的只有x64版本。mfc在显示图片的时候是4字节对齐的,所以要把openc...

OpenCV在MFC中的使用

1.调用固定文档型1.1 老外网页: www.lund.gl/ImageProcess/OpenCV.html:using opencv with mfc,在wiki中有链接1.2刘、于教材例子与上面...
  • Augusdi
  • Augusdi
  • 2013年05月05日 17:23
  • 1758

在MFC中使用OpenCV

在MFC中使用OpenCV目录 [隐藏]1 例程下载2 OpenCV与MFC3 StretchDIBits 函数4 演示程序5 像素数据类型6 图像镜像7 驱动模式与人机交互8 程序移植例9 形参书写...
  • Augusdi
  • Augusdi
  • 2013年04月29日 23:01
  • 4752

MFC调用OpenCV的程序移植问题——静态编译

MFC调用OpenCV的程序移植问题——内存泄露和静态编译

opencv2.3没有CvvImage的解决办法

转自:http://blog.sina.com.cn/s/blog_79a0eceb0100ybg0.html 如何在OpenCV2.3中实现CvvImage,根据网络各个高手的方法,我自己的总...

OpenCV高版本中CImage(CvvImage)取消以后的替代方法

在OpenCV高版本里CvvImage类被取消,如果想继续沿用以前的CvvImage,其实很简单,只要搜到CvvImage的源代码(.h和.cpp)。在自己的工程里面增加一个新的CvvImage类就可...

VS2013 MFC + OpenCV3.0 打开图片

本文仅涉及一些核心步骤,具体 OpenCV 的配置以及其他的细节问题,请参考 VS2010 / MFC + OpenCV 2.4.1打开图片。1. 新建 MFC 对话框项目基于对话框,不使用Unico...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于Dialog的MFC对话框上利用OpenCV 3.0显示图片
举报原因:
原因补充:

(最多只允许输入30个字)