当前位置:职场发展 > vs2010mfc读入任意一幅图像的opencv2.4.9代码_使用VS2010+OpenCV2.4.9简单图像水印代码

vs2010mfc读入任意一幅图像的opencv2.4.9代码_使用VS2010+OpenCV2.4.9简单图像水印代码

  • 发布:2023-09-22 20:23

学习openCV也有一段时间了,今天想着怎么把图片显示在MFC上,就开始百度找案例和方法,结合了许多大神的博客,总结了他们的东西,完成了自己想要的东西,把自己做的过程贴出来,仅供参考。

参考的其中三个博客链接如下:

https://www.sychzs.cn/sunrong0511/article/details/52052692

https://www.sychzs.cn/wht18720080085/article/details/69259241

https://www.sychzs.cn/sxlsxl119/article/details/51258998

1.建立MFC工程文件

2,

由于以后的代码会用到CvvImage类,而opencv2.3以后就去掉了对它的支持,这里先介绍添加CvvImage支持的方法,直接能用的可以略过这一步。

点“头文件”和“源文件”,单击右键,新建项

这里附上两个文件的源码方便使用:

CvvImage.h

#pragma once

#ifndef CVVIMAGE_CLASS_DEF

#define CVVIMAGE_CLASS_DEF

#include "opencv.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

);

#endif

protected:

IplImage

*

m_img

;

};

typedef

CvvImage

CImage

;

#endif

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

,

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

::

Fill

(

int

color

)

{

cvSet

(

m_img

,

cvScalar

(

color

&

255

,(

color

>>

8

)

&

255

,(

color

>>

16

)

&

255

,(

color

>>

24

)

&

255

)

);

}

3.在需要引用该类的地方添加如下引用:

在newgrayANDbwDlg.cpp中添加包含头文件:

在newgrayANDbwDlg.h?中添加包含文件:

4.添加显示图片函数DrawPicToHDC,在类视图中,在cnewgrayANDbwDlg单击右键添加void类型函数

(注:此时,我们要添加的是UINT型和IplImage型,在这里可能添加不成,就不必在此添加参数名和参数列表,后面自己在函数里面添加)

自己讲“void”改为“IplImage * img, UINT ID”:

void CnewgrayANDbwDlg::DrawPicToHDC(IplImage * img, UINT ID){ CDC *pDC=GetDlgItem(ID)->GetDC();?? HDC hDC=pDC->GetSafeHdc();?? CRect rect;?? GetDlgItem(ID)->GetClientRect(&rect);?? CvvImage cimg;?? cimg.CopyOf(img);?? cimg.DrawToHDC(hDC,&rect);?? ReleaseDC(pDC);??}IplImage *Src=NULL;??IplImage *TheImage=NULL;??

CString m_strPicPath;//弹出选择图片对话框?

(注:最后三行要在大括号外,否则会报错,且这个函数必须在其他的控件之前,否则会报错:没有定义的标识符

改完了newgrayANDbwDlg.cpp这个里面的参数名,还要改newgrayANDbwDlg.h里面的?):

5.为控件“打开文件”、“灰度图”和“二值图”添加消息响应函数,双击控件,在各自的函数框中添加如下函数:

void CnewgrayANDbwDlg::OnBnClickedButton1(){ // TODO: 在此添加控件通知处理程序代码? ?CFileDialog dlg(true,_T("*.bmp"),NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,_T("image file(*.bmp;*.jpg)|*.bmp;*.jpg|All Files(*.*)|*.*|"),NULL);?? dlg.m_ofn.lpstrTitle = _T("Open Image");// 打开文件对话框的标题名?? if( dlg.DoModal() != IDOK )? ? ? ? // 判断是否获得视频?? return;?? m_strPicPath = dlg.GetPathName();? ? ? ? ? ?//获取图片路径?? m_strPicPath.Replace(_T("//"),_T(""));?? TheImage=cvLoadImage((CT2CA)m_strPicPath,1); //读取彩色图?? DrawPicToHDC(TheImage,IDC_STATIC);?}void CnewgrayANDbwDlg::OnBnClickedButton2(){ // TODO: 在此添加控件通知处理程序代码 Src = cvLoadImage((CT2CA)m_strPicPath,0);//读取灰度图片??? ? DrawPicToHDC(Src,IDC_STATIC);?}void CnewgrayANDbwDlg::OnBnClickedButton3(){ // TODO: 在此添加控件通知处理程序代码? ?cvCvtColor(TheImage,Src,CV_BGR2GRAY);?? ? ?IplImage *dst=cvCreateImage(cvGetSize(Src),IPL_DEPTH_8U, 1);?? ? ? cvThreshold(Src,dst,40, 255 ,CV_THRESH_BINARY);?? ? ? DrawPicToHDC(dst,IDC_STATIC);?

}

6.编译运行,效果图如下:

上面的描述已经很清楚了,按照这个一步步做就可以做出来,这里贴出我做的整个工程文件,下载下来解压缩,在配置了openCV的VS上可以直接

编译运行,有兴趣的可以下载。

下载链接:https://www.sychzs.cn/download/qq_40969467/10483778

问题:VS2010 / MFC + OpenCV 显示图片

链接:http://www.sychzs.cn/article/f71d60375ddd411ab641d1e3.html

说明:可以了解一个基本的应用OpenCV的MFC程序的基本流程。(程序和视频)

问题:VS2010 / MFC + OpenCV 读取摄像头

链接:http://www.sychzs.cn/watkinsong/article/details/7360941

说明:基本的过程和第一个问题基本类似,可以仿照前面的建立工程,不同的只是函数的处理。仿照博客的步骤可以完成要求,就是工程调试的时候在关闭摄像头时有点小细节,没有添加位图资源,就是关闭摄像头,picture控件停留关闭前的画面,当就是添加"位图资源",关闭摄像头画面编程黑的。(程序)

本文代码实现了简单的数字水印功能,即将一个掩模图像(二值图像)的信息隐藏在一个灰度图像的最低有效位上。

#include "StdAfx.h"

#include

#include

#include

#include

#include

#include

void kcvWatermarking(IplImage* img,IplImage* mask)

{

int w=img->width;

int h=img->height;

// 确保mask中只有黑白两种灰度值

cvThreshold(mask,mask,128,255,CV_THRESH_BINARY);

for(int i=0;i

{

for(int j=0;j

{

if(CV_IMAGE_ELEM(mask,uchar,i,j))

{

CV_IMAGE_ELEM(img,uchar,i,j)|=0x1;

}

else

{

CV_IMAGE_ELEM(img,uchar,i,j)&=0xfe;

}

}

}

}

void kcvGetWatermarking(IplImage* img,IplImage* dst)

{

int w=img->width;

int h=img->height;

for(int i=0;i

{

for(int j=0;j

{

if(CV_IMAGE_ELEM(img,uchar,i,j)&0x1)

{

CV_IMAGE_ELEM(dst,uchar,i,j)=0;

}

else

{

CV_IMAGE_ELEM(dst,uchar,i,j)=255;

}

}

}

}

int main( int argc, char** argv )

{

IplImage* img=cvLoadImage("lena.jpg",0);

IplImage* mask=cvCreateImage(cvGetSize(img),8,1);

IplImage* dst=cvCreateImage(cvGetSize(img),8,1);

cvSetZero(mask);

CvFont font=cvFont(2);

char text[]="minmin, i love you!";

cvPutText(mask,text,cvPoint(50,50),&font,CV_RGB(255,255,255));

cvNamedWindow("img");

cvNamedWindow("min");

cvShowImage("img",img);

cvShowImage("min",mask);

// 执行水印

kcvWatermarking(img,mask);

cvNamedWindow("comp");

cvShowImage("comp",img);

// 获得水印

kcvGetWatermarking(img,dst);

cvNamedWindow("watermarking");

cvShowImage("watermarking",dst);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&img);

cvReleaseImage(&mask);

cvReleaseImage(&dst);

system("pause");

return 0;

}

相关文章