- // ImageView.cpp : implementation of the CImageView class
- //
- #include "stdafx.h"
- #include "Image.h"
- #include "ImageDoc.h"
- #include "ImageView.h"
- /////////begin/////////////////////////////////
- #include "cv.h" // include core library interface
- #include "highgui.h" // include GUI library interface
- #pragma comment(lib, "cv" )
- #pragma comment(lib, "highgui" )
- #pragma comment(lib, "cxcore" )
- CString imgfilepath;
- IplImage* img=0; // Declare IPL/OpenCV image pointer
- ////////end/////////////////////////////////
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CImageView
- IMPLEMENT_DYNCREATE(CImageView, CView)
- BEGIN_MESSAGE_MAP(CImageView, CView)
- //{{AFX_MSG_MAP(CImageView)
- ON_COMMAND(ID_IMAGE_OPENFILE, OnImageOpenFile)
- ON_COMMAND(ID_IMAGE_SOBEL, OnImageSobel)
- ON_COMMAND(ID_IMAGE_LAPLACE, OnImageLaplace)
- ON_COMMAND(ID_IMAGE_CANNY, OnImageCanny)
- ON_COMMAND(ID_IMAGE_HISTGRAM, OnImageHistgram)
- ON_COMMAND(ID_IMAGE_RESIZE, OnImageResize)
- ON_COMMAND(ID_IMAGE_ROTATION, OnImageRotation)
- ON_COMMAND(ID_IMAGE_EROSION, OnImageErosion)
- ON_COMMAND(ID_IMAGE_OPEN, OnImageOpen)
- ON_COMMAND(ID_IMAGE_HOUGH_LINE, OnImageHoughLine)
- ON_COMMAND(ID_IMAGE_HOUGH_CIRCLE, OnImageHoughCircle)
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
- END_MESSAGE_MAP()
- // CImageView construction/destruction
- CImageView::CImageView()
- {
- // TODO: add construction code here
- }
- CImageView::~CImageView()
- BOOL CImageView::PreCreateWindow(CREATESTRUCT& cs)
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CView::PreCreateWindow(cs);
- // CImageView drawing
- void CImageView::OnDraw(CDC* pDC)
- CImageDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: add draw code for native data here
- // CImageView printing
- BOOL CImageView::OnPreparePrinting(CPrintInfo* pInfo)
- // default preparation
- return DoPreparePrinting(pInfo);
- void CImageView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- // TODO: add extra initialization before printing
- void CImageView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- // TODO: add cleanup after printing
- // CImageView diagnostics
- void CImageView::AssertValid() const
- CView::AssertValid();
- void CImageView::Dump(CDumpContext& dc) const
- CView::Dump(dc);
- CImageDoc* CImageView::GetDocument() // non-debug version is inline
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageDoc)));
- return (CImageDoc*)m_pDocument;
- #endif //_DEBUG
- // CImageView message handlers
- void CImageView::OnImageOpenFile()
- // TODO: Add your command handler code here
- CFileDialog dlg(TRUE, _T("*.bmp"), "",
- OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
- "image files (*.bmp; *.jpg) |*.bmp;*.jpg|AVI files (*.avi) |*.avi|All Files (*.*)|*.*||",NULL);
- char title[]= {"Open Image"};
- dlg.m_ofn.lpstrTitle= title;
- if (dlg.DoModal() == IDOK)
- {
- imgfilepath= dlg.GetPathName();
- if (img!=0)
- cvReleaseImage( &img );
- img = cvvLoadImage( imgfilepath ); // load image
- cvvNamedWindow( "Original Image", 1 ); // create a window
- cvvShowImage( "Original Image", img ); // display the image on window
- }
- void CImageView::OnImageSobel()
- //定義的變量
- IplImage* pImage= NULL; // 聲明IplImage 變量
- IplImage* pImgSobelgray= NULL;// 聲明IplImage 變量,用于灰階圖像Sobel變換
- IplImage* pImg8u= NULL;// 聲明IplImage 變量,用于圖像格式轉換
- IplImage* pImg8uSmooth= NULL;// 聲明IplImage 變量,用于存儲平滑後的圖像
- IplImage* pImgColor= NULL;// 聲明IplImage 變量,用于Sobel變換
- IplImage* pImgSobelcolor= NULL;// 聲明IplImage 變量,用于彩色圖像Sobel變換
- IplImage* pImgPlanes[3] = { 0, 0, 0 };
- //将已讀入系統的圖像複制一份
- pImage=cvCloneImage( img );
- //建立和原始圖像一樣圖像記憶體區,圖像元素的位深度設為IPL_DEPTH_8U
- //即無符号8位整型
- pImg8u = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U, 1);
- pImg8uSmooth = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U, 1);
- //對灰階圖像進行Sobel變換
- //将彩色圖像轉換為灰階圖像
- cvCvtColor(pImage, pImg8u, CV_BGR2GRAY);
- //對圖像進行高斯濾波
- cvSmooth( pImg8u, pImg8uSmooth,CV_GAUSSIAN,3,0,0);
- //建立一新圖像記憶體區,圖像元素的位深度設為IPL_DEPTH_16S有符号16位整型
- //因為cvSobel函數要求目标圖像必須是16-bit圖像
- pImgSobelgray = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_16S, 1);
- //計算一階 x方向的圖像差分,可根據需要設定參數
- cvSobel(pImg8uSmooth, pImgSobelgray,0,1,3);
- //将圖像格式再轉換回來,用于顯示
- cvConvertScaleAbs(pImgSobelgray,pImg8u,1,0 ) ;
- //建立視窗,顯示圖像
- cvvNamedWindow( "Sobel gray Image", 1 );
- cvvShowImage( "Sobel gray Image", pImg8u );
- //對彩色圖像進行Sobel變換
- //建立3個圖像記憶體區,分别存儲圖像3個通道,圖像元素的位深度設為IPL_DEPTH_8U
- int i;
- for( i = 0; i < 3; i++ )
- pImgPlanes[i] = cvCreateImage( cvSize(pImage ->width, pImage ->height), 8, 1 );
- //建立一新圖像記憶體區,圖像元素的位深度設為IPL_DEPTH_16S有符号16位整型
- pImgSobelcolor = cvCreateImage( cvSize(pImage ->width, pImage ->height), IPL_DEPTH_16S, 1 );
- //要求輸出圖像是 16 位有符号的
- pImgColor = cvCreateImage( cvSize(pImage ->width, pImage ->height), 8, 3 );
- //将彩色圖像分成3 個單通道圖像
- cvCvtPixToPlane(pImage, pImgPlanes[0], pImgPlanes[1], pImgPlanes[2], 0 );
- for( i = 0; i < 3; i++ )
- {
- //分别對每通道圖像進行Sobel變換
- cvSobel( pImgPlanes[i], pImgSobelcolor,0,1,3 );
- //轉化為8位的圖像
- cvConvertScaleAbs(pImgSobelcolor, pImgPlanes[i], 1, 0 );
- }
- //将各通道圖像進行合并
- cvCvtPlaneToPix( pImgPlanes[0], pImgPlanes[1], pImgPlanes[2], 0, pImgColor);
- cvvNamedWindow( "Sobel color Image", 1 );
- cvvShowImage( "Sobel color Image", pImgColor);
- //等待按鍵
- cvWaitKey(0);
- //鎖毀視窗
- cvDestroyWindow( " Sobel gray Image " );
- cvDestroyWindow( " Sobel color Image " );
- //将程式開始定義的變量釋放
- cvReleaseImage( & pImage);
- cvReleaseImage( & pImgSobelgray);
- cvReleaseImage( & pImgSobelcolor);
- cvReleaseImage( & pImg8u);
- cvReleaseImage( & pImg8uSmooth);
- void CImageView::OnImageLaplace()
- //定義的變量
- IplImage* pImage= NULL;// 聲明IplImage 變量
- IplImage* pImgLaplace= NULL;// 聲明IplImage 變量,用于Laplace變換
- pImg8uSmooth= cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U, 1);
- cvCvtColor(pImage,pImg8u, CV_BGR2GRAY);
- //對灰階圖像進行高斯濾波
- //此函數和cvSobel函數一樣要求目标圖像必須是16-bit圖像
- //如果給8-bit目标圖像會報錯
- pImgLaplace = cvCreateImage(cvGetSize(img),IPL_DEPTH_16S, 1);
- cvLaplace(pImg8uSmooth, pImgLaplace,3);
- //将圖像格式再轉換回來,用于顯示
- cvConvertScaleAbs(pImgLaplace,pImg8u,1,0 ) ;
- cvvNamedWindow( "laplace gray Image", 1 );
- cvvShowImage( "laplace gray Image", pImg8u );
- //銷毀視窗
- cvDestroyWindow( " laplace gray Image " );
- cvReleaseImage( & pImgLaplace);
- //cvReleaseImage( & pImg8uSmooth);
- void CImageView::OnImageCanny()
- IplImage* pImgCanny= NULL;// 聲明IplImage 變量,用于灰階圖像Canny變換
- pImgCanny = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U, 1);
- //對灰階圖像進行Canny變換
- //cvCanny的源圖像必須是灰階圖像
- cvCanny(pImg8uSmooth,pImgCanny, 100, 200, 3 );
- cvConvertScaleAbs(pImgCanny,pImg8u,1,0 ) ;
- cvvNamedWindow( "Canny Image", 1 );
- cvvShowImage( "Canny Image", pImg8u);
- cvDestroyWindow( " Canny Image " );
- cvReleaseImage( & pImgCanny);
- void CImageView::OnImageHistgram()
- int hist_size = 255; //直方圖的針數
- float range_0[]={0,256}; //第0維數值的變化範圍
- float* ranges[] = { range_0 };//第1維數值的變化範圍
- int i, bin_w; //下标号
- float max_value = 0, min_value = 0; //直方圖數值的max和min
- int min_idx = 0, max_idx = 0; //對應上述max和min數值時的下标号
- double mean = 0, variance = 0; //用于存放平均值(mean)和變化量(variance)的變量
- IplImage* pImgGray= NULL;// 聲明IplImage 變量
- //将已讀入系統的圖像一份
- pImgGray = cvCreateImage(cvSize(pImage->width,pImage->height),
- IPL_DEPTH_8U, 1);
- //轉換成灰階圖像
- cvCvtColor(pImage, pImgGray, CV_BGR2GRAY);
- //建立一個矩形區域
- CvRect rect = cvRect(0, 0, 500, 600 );
- //把矩形作用于圖像以建立一個感興趣區(region of interest, ROI)
- cvSetImageROI(pImgGray, rect); // 設定 ROI
- //建立一個圖像用來存放直方圖
- IplImage* histImage = cvCreateImage(cvSize(320,200), 8, 1);
- //建立一個指定尺寸的直方圖,用于存放從圖像獲得的資訊
- CvHistogram* hist =
- cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
- //計算直方圖并作用到hist變量
- cvCalcHist( &pImgGray, hist, 0, NULL );
- //得到直方圖中的最大最小值及其标号
- cvGetMinMaxHistValue( hist, &min_value, &max_value, &min_idx, &max_idx);
- //縮放這些針值以容入圖像内
- cvScale( hist->bins, hist->bins, ((double)histImage->height)/max_value, 0 );
- //設所有直方圖的數值為255
- cvSet( histImage, cvScalarAll(255), 0 );
- //建立一個比例因子以沿寬度縮放
- bin_w = cvRound((double)histImage->width/hist_size);
- for( i = 0; i < hist_size; i++ ) {
- //把直方圖畫到圖像中
- cvRectangle( histImage, cvPoint(i*bin_w, histImage->height),
- cvPoint((i+1)*bin_w,
- histImage->height - cvRound(cvGetReal1D(hist->bins,i))),
- cvScalarAll(0), -1, 8, 0 );
- //得到目前數值
- float* bins = cvGetHistValue_1D(hist,i);
- //增加均值
- mean += bins[0];
- // std::cout<< bins[0] << " " << bins[1] << std::endl;
- //均值計算完畢
- mean /= hist_size;
- //有了均值後就可以計算變化量了(variance)
- variance += pow((bins[0] - mean),2);
- //變化量計算完畢
- variance /= hist_size;
- // std::cout << "Histogram Mean: " << mean << std::endl;
- // std::cout << "Variance: " << variance << std::endl;
- // std::cout << "Standard Deviation: " << sqrt(variance) << std::endl;
- cvNamedWindow("Original", 0);
- cvShowImage("Original", pImage );
- cvNamedWindow("Gray", 0);
- cvShowImage("Gray", pImgGray );
- cvNamedWindow("Histogram", 0);
- cvShowImage("Histogram", histImage );
- CvFont *pfont=new CvFont;
- cvInitFont(pfont,CV_FONT_HERSHEY_SIMPLEX ,0.8f,0.8f,0,2);
- CString Result="Histogram Mean: ";
- CString str; str.Format("%f", mean);
- Result+=str+"\n";
- cvPutText(histImage,Result,cvPoint(80,80),pfont,CV_RGB(255,0,0));
- delete pfont;
- cvReleaseImage(&histImage);
- cvReleaseImage(&pImgGray);
- cvDestroyWindow("Original");
- cvDestroyWindow("Gray");
- cvDestroyWindow("Histogram");
- void CImageView::OnImageResize()
- IplImage* pImgNew= NULL;// 聲明IplImage 變量
- CFileDialog dlg(TRUE, _T("*.bmp"), "",
- OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
- char title[]= {"Open Image again"};
- if (pImgNew!=0)
- cvReleaseImage( &pImgNew );
- //載入第二幅圖像
- pImgNew = cvvLoadImage( imgfilepath );
- //建立視窗,顯示第二幅圖像
- cvvNamedWindow( "Second Image", 1 );
- cvvShowImage( "Second Image", pImgNew );
- //縮放圖像,使其尺寸與第二幅圖像相等
- cvResize( pImage, pImgNew, CV_INTER_NN );
- //建立視窗,顯示縮放後的幅圖像
- cvvNamedWindow( "Resized Image", 1 );
- cvvShowImage( "Resized Image", pImgNew );
- cvReleaseImage(&pImage);
- cvReleaseImage(&pImgNew);
- cvDestroyWindow("Second Image");
- cvDestroyWindow("Resized Image");
- void CImageView::OnImageRotation()
- int angle = 30; //旋轉30度
- int opt = 0; // 1: 加縮放
- // 0: 僅僅旋轉
- double factor; //縮放因子
- IplImage* pImgRotation= NULL;// 聲明IplImage 變量
- pImgRotation=cvCloneImage( img );
- //建立M矩陣
- float m[6];
- // Matrix m looks like:
- //
- // [ m0 m1 m2 ] ===> [ A11 A12 b1 ]
- // [ m3 m4 m5 ] [ A21 A22 b2 ]
- CvMat M = cvMat( 2, 3, CV_32F, m );
- int w = img->width;
- int h = img->height;
- if(opt) // 旋轉加縮放
- factor = (cos(angle*CV_PI/180.) + 1.0)*2;
- else // 僅僅旋轉
- factor = 1;
- m[0] = (float)(factor*cos(-angle*CV_PI/180.));
- m[1] = (float)(factor*sin(-angle*CV_PI/180.));
- m[3] = -m[1];
- m[4] = m[0];
- // 将旋轉中心移至圖像中間
- m[2] = w*0.5f;
- m[5] = h*0.5f;
- // dst(x,y) = A * src(x,y) + b
- cvZero(pImgRotation);
- cvGetQuadrangleSubPix( pImage, pImgRotation, &M);
- //建立視窗,顯示圖像
- cvNamedWindow( "Rotation Image", 1 );
- cvShowImage( "Rotation Image", pImgRotation );
- cvReleaseImage(&pImgRotation);
- cvDestroyWindow("Rotation Image");
- void CImageView::OnImageErosion()
- IplImage* pImgErode= NULL;// 聲明IplImage 變量
- IplImage* pImgDilate= NULL;// 聲明IplImage 變量
- pImgErode=cvCloneImage( img );
- pImgDilate=cvCloneImage( img );
- //對輸入圖像使用預設的3×3 長方形結構元素進行腐蝕
- cvErode( pImgErode, pImgErode, 0, 2 );
- //對輸入圖像使用預設的3×3 長方形結構元素進行膨脹
- cvDilate( pImgDilate, pImgDilate, 0, 2 );
- cvNamedWindow("Erosion", 0);
- cvShowImage("Erosion", pImgErode );
- cvNamedWindow("Dilation", 0);
- cvShowImage("Dilation", pImgDilate );
- cvReleaseImage(&pImgErode);
- cvReleaseImage(&pImgDilate);
- cvDestroyWindow("Erosion");
- cvDestroyWindow("Dilation");
- void CImageView::OnImageOpen()
- IplImage* pImgOpen= NULL;// 聲明IplImage 變量
- IplImage* pImgClose= NULL;// 聲明IplImage 變量
- IplConvKernel* pKernel =NULL;// 聲明IplConvKernel 變量
- pImgOpen=cvCloneImage( img );
- pImgClose=cvCloneImage( img );
- //建立立結構元素
- pKernel = cvCreateStructuringElementEx(15,15,8,8,CV_SHAPE_ELLIPSE,NULL);
- //進行開運算
- cvErode(pImgOpen,pImgOpen,pKernel,1);
- cvDilate(pImgOpen,pImgOpen,pKernel,1);
- //進行閉運算
- cvDilate(pImgClose,pImgClose,pKernel,1);
- cvErode(pImgClose,pImgClose,pKernel,1);
- cvNamedWindow("Open", 0);
- cvShowImage("Open", pImgOpen );
- cvNamedWindow("Close", 0);
- cvShowImage("Close", pImgClose );
- cvReleaseImage(&pImgOpen);
- cvReleaseImage(&pImgClose);
- cvDestroyWindow("Open");
- cvDestroyWindow("Close");
- void CImageView::OnImageHoughLine()
- CvMemStorage* storage = NULL;// 聲明storage 變量,用于存儲檢測到的線段
- CvSeq* lines = NULL; //聲明lines變量,用于存儲直線的輪廓
- //将已讀入系統的圖像複制兩份,一份作為背景圖像
- //建立記憶體空間
- storage = cvCreateMemStorage(0);
- //利用Canny變換找出圖像邊緣
- cvCanny( pImg8u, pImgCanny, 50, 500, 3 );
- //Hough線變換
- lines = cvHoughLines2( pImgCanny, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 30, 10 );
- //在原圖上畫紅直線
- for( i = 0; i < lines->total; i++ )
- CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
- cvLine( pImage, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
- cvNamedWindow( "Hough Line Transform", 1 );
- cvShowImage( "Hough Line Transform", pImage);
- cvDestroyWindow( " Hough Line Transform " );
- void CImageView::OnImageHoughCircle()
- CvSeq* circles = NULL;
- if(img->nChannels != 1)
- cvCvtColor( pImage, pImg8u, CV_BGR2GRAY );
- else
- cvCopy(pImage, pImg8u);
- //平滑化
- cvSmooth( pImg8u, pImg8u, CV_GAUSSIAN, 7, 7 );
- //Hough圓變換
- circles = cvHoughCircles( pImg8u, storage, CV_HOUGH_GRADIENT, 2, pImg8u->height/4, 250, 55 );
- // 畫出識别出的圓
- for( i = 0; i < circles->total; i++ )
- float* p = (float*)cvGetSeqElem( circles, i );
- cvCircle(pImage, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
- cvNamedWindow( "Hough Circle Transform", 1 );
- cvShowImage( "Hough Circle Transform", pImage);
- cvDestroyWindow( " Hough Circle Transform " );