Recently, we have to work on digital image processing projects. We all say Vs + MFC + opencv is very useful, so I tried it. First, I went to the home page of opencv chinaopencv Chinese edition and found some very good tutorials. I use Visual Studio 2005 and opencv 2.3.1. However, opencv
In China, it seems that only the earlier version of opencv Based on vs2005 has been set up, or the opencv2.0 or later versions have been set up on platforms such as vs2008 and vs2010. Since I have used vs2010 and vs2005, I feel that the difference between the two compilers is very small compared with vs2005 and vc6.0, so I successfully created the opencv2.3.1 environment on vs2005 by using the opencv2.3.1 environment created on vs2008/vs2010. Next, I started to make the MFC-based opencv. I followed the relevant tutorials on opencv China and referred to a lot of posts to quickly use opencv in MFC, I almost imitated it step by step and reported many errors. In order to modify these bugs, I had a hard time solving them. The following is a description of the project error information and how to modify it. I hope this will help you. The following error occurs after completing the tutorial step by step on the official website:
Log generation started: Project: copencv_ex2, configuration: Debug | Win32 command line is creating a temporary file "D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ debug \ rsp00000149925924.rsp ", the content is [/OD/D "Win32"/D "_ WINDOWS"/D "_ debug"/GM/ESCs/rtc1/MTD/YU "stdafx. H "/FP" Debug \ copencv_ex2.pch "/FO" Debug \ "/FD" Debug \ vc80.pdb "/W3/C/wp64/Zi/TP ". \ cvvimage. CPP "". \ copencv_ex2view.cpp "". \ copencv_ex2doc.cpp "". \ copencv_ex2.cpp "begin is creating a command line named cl.exe @" D: \ image C ++ \ C ++ \ copencv_ex2 \ copencv_ex2 \ debug \ rsp00000149925924.rsp "/nologo/errorreport: prompt" the output window is being compiled... cvvimage. CPP is generating code... compiling... copencv_ex2.cppd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c2146: syntax error: Missing ";" (before identifier "m_image) d: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: The type specifier is missing-it is assumed to be Int. Note: C ++ does not support the default intd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: the type specifier is missing-it is assumed to be Int. Note: C ++ does not support intcopencv_ex2doc.cppd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c2146: syntax error: Missing "; "(before the identifier" m_image ") D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: the type specifier is missing-it is assumed to be Int. Note: C ++ does not support the default intd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: the type specifier is missing-it is assumed to be Int. Note: C ++ does not support the default intd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.cpp (90): Error c2065: "m_image ": undeclared identifier D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.cpp (90): Error c2228: ". the left side of load must have a class/structure/the Union type is 'unknown-type' D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.cpp (101): Error c2228: ". the left side of save must have a class/structure/the Union type is "'unknown-type'" copencv_ex2view.cppd: \ image C ++ \ c ++ \ copencv_ex2 \ Copencv_ex2 \ copencv_ex2doc.h (18): Error c2146: syntax error: Missing ";" (before identifier "m_image") D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: The type specifier is missing-it is assumed to be Int. Note: C ++ does not support the default intd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (18): Error c4430: the type specifier is missing-it is assumed to be Int. Note: C ++ does not support the default intd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2view.cpp (58): Error c2065: "cimage ": undeclared identifier D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2view.cpp (58): Error c2065: "IMG": Undeclared identifier D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2view.cpp (58): Error c2039: "m_image": Not a member of "ccopencv_ex2doc" D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (10): See the statement "ccopencv_ex2doc" D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2view.cpp (61): Error c2228: ". the left side of drawtohdc must have a class/structure/the Union type is 'unknown-type'. The code is being generated... the generated logs are stored in "file: // D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ debug \ buildlog.htm" copencv_ex2-16 errors, 0 warnings
Explanation: this is because the standard tutorial uses the lower version of opencv and cimage is not defined. You need to add the cvvimage. h and cvvimage. cpp files to the project:
Cvvimage. h
#pragma once#ifndef CVVIMAGE_CLASS_DEF#define CVVIMAGE_CLASS_DEF#include "opencv.hpp"/* CvvImage class definition */class CvvImage{public:CvvImage();virtual ~CvvImage();/* Create image (BGR or grayscale) */virtual bool Create( int width, int height, int bits_per_pixel, int image_origin = 0 );/* Load image from specified file */virtual bool Load( const char* filename, int desired_color = 1 );/* Load rectangle from the file */virtual bool LoadRect( const char* filename,int desired_color, CvRect r );#if defined WIN32 || defined _WIN32virtual 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/* Save entire image to specified file. */virtual bool Save( const char* filename );/* Get copy of input image ROI */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);/* width and height of ROI */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 );/* draw to highgui window */virtual void Show( const char* window );#if defined WIN32 || defined _WIN32/* draw part of image to the specified DC */virtual void Show( HDC dc, int x, int y, int width, int height,int from_x = 0, int from_y = 0 );/* draw the current image ROI to the specified rectangle of the destination DC */virtual void DrawToHDC( HDC hDCDst, RECT* pDstRect );#endifprotected: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 errorreturn false;}if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h ){if( m_img && m_img->nSize == sizeof(IplImage))Destroy();/* prepare IPL header */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;}/* truncate r to source image */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 contextHALFTONE );}else{SetStretchBltMode(hDCDst, // handle to device contextCOLORONCOLOR );}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) );}
After adding the code, do not forget to add the. h file to the. View. h file. Re-compile the code, and an error will still be reported:
Compiling output window... copencv_ex2doc.cppd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.cpp (90): Error c2664: "cvvimage: Load ": the conversion of parameter 1 from "lpctstr" to "const char *" is not related to the type to which it points. Conversion requires reinterpret_cast, C style conversion, or function style conversion D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.cpp (101): Error c2664: "cvvimage: Save ": the conversion of parameter 1 from "lpctstr" to "const char *" is not related to the type to which it points. Conversion requires reinterpret_cast, C style conversion, or function style conversion copencv_ex2view.cppd: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2view.cpp (61): Error c2039: "getsafehdc": Not a member of "ccopencv_ex2doc" D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ copencv_ex2doc.h (10): See the statement of "ccopencv_ex2doc" generating code... the generated logs are stored in "file: // D: \ image C ++ \ c ++ \ copencv_ex2 \ copencv_ex2 \ debug \ buildlog.htm" copencv_ex2-3 errors, 0 warnings
Cause: the first two errors are caused by the uincode character set used in the environment. Change this option to "not set.
The second error is that the PDC in the Void ccopencv_ex2view: ondraw (CDC */* PDC */) function in the copencv_ex2view.cpp file is commented out. Open the annotation and put an IMG in the function. replace pdoc in drawtohdc (pdoc-> getsafehdc (), R) with PDC. The modified code is as follows:
Void ccopencv_ex2view: ondraw (CDC * PDC) {ccopencv_ex2doc * pdoc = getdocument (); // assert_valid (pdoc); If (! Pdoc) return; // todo: add the drawing code assert_valid (pdoc) for the local data here; // todo: Add draw code for native data herecimage & IMG = pdoc-> m_image; crect R; getclientrect (& R); IMG. drawtohdc (PDC-> getsafehdc (), R );}
After the modification, run the command and find that there is still an error: 1> link: Fatal error lnk1104: Unable to open the file "cxcore. lib"
The reason is that the names of these libraries are library files of earlier versions of opencv. For opencv2.3.1, you need to change the names. Choose "Project Properties"> "linker"> "input"> "add dependency" to replace the following content:
Change cxcore. Lib cv. Lib highgui. lib to opencv_core231d.lib.
Opencv_highgui231d.lib
Opencv_imgproc231d.lib
Opencv_legacy231d.lib
Opencv_ml231d.lib
Opencv_objdetect231d.lib
Opencv_ts231d.lib
Opencv_video231d.lib
Some of these projects are not required, but I do not know which ones should be required or not, so I simply fill them in. Click OK to complete the compilation. I have uploaded the Modified Solution to csdn. You are welcome to download it. The resource name is "vs2005 using opencv2.3.1 in MFC
"
. I believe that this tutorial can run well not only on vs2005, but also on vs2008 and vs2010!
Everything is hard at the beginning. I believe that with this good start, it will be much easier to do it again!