OpenCV形态学相关函数的使用测试。

来源:互联网 发布:淘宝差评处理技巧 编辑:程序博客网 时间:2024/04/29 00:36

其中还包含了在书上出的题目代码。有点点乱哈。。。大笑

#include "cv.h"#include "highgui.h"const char szTestImage[] = "D:\\cvImg\\lin.jpg";//这2个图像是用来测试从图像中分割出变动的区域的。也就是这两张图像需要类似,但有点点不一样。目的就是找到这不一样的地方,用于视频目标跟踪。const char szSplitImage1[] = "D:\\cvImg\\src1.jpg";const char szSplitImage2[] = "D:\\cvImg\\src2.jpg";//这2个图像是用来绝对值求差用的,类似上面的图像,也是有点不一样的图像,检测出不同的地方。const char szAbsDiffImage1[] = "D:\\cvImg\\gujinlin1.jpg";const char szAbsDiffImage2[] = "D:\\cvImg\\gujinlin2.jpg";int main(int argc, char** argv){//原图IplImage* pSourceImage = cvLoadImage(szTestImage);//灰度图IplImage* pGrayscaleImage = cvCreateImage(cvGetSize(pSourceImage), 8, 1);cvCvtColor(pSourceImage, pGrayscaleImage, CV_RGB2GRAY);//这两个方法都是灰度化图像//cvConvertImage(pSourceImage, pGrayscaleImage);//这两个方法都是灰度化图像//二值图IplImage* pBinaryImage = cvCloneImage(pGrayscaleImage);cvThreshold(pBinaryImage, pBinaryImage, 128, 255, CV_THRESH_BINARY);//二值化图像//自适应阈值,二值化IplImage* pAdaptiveBinaryImage = cvCloneImage(pGrayscaleImage);cvAdaptiveThreshold(pAdaptiveBinaryImage, pAdaptiveBinaryImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 3, 5);//腐蚀,膨胀可以使用非二值图,比如原图/灰度图。//腐蚀IplImage* pErodeImage = cvCloneImage(pBinaryImage);cvErode(pErodeImage, pErodeImage, NULL, 1);//为NULL使用3*3核,1为迭代次数。//膨胀IplImage* pDilate = cvCloneImage(pBinaryImage);cvDilate(pDilate, pDilate, NULL, 1);//为NULL使用3*3核,1为迭代次数。//开运算:去除小的明亮区域,并且剩余的明亮区域被隔绝,但其大小不变。IplImage* pOpenImage = cvCloneImage(pBinaryImage);cvMorphologyEx(pOpenImage, pOpenImage, NULL, NULL, CV_MOP_OPEN, 1);//闭运算:消除低亮度的孤立点,亮的区域连在一起,但他们基本的大小不变。IplImage* pCLoseImage = cvCloneImage(pBinaryImage);cvMorphologyEx(pCLoseImage, pCLoseImage, NULL, NULL, CV_MOP_CLOSE, 1);//形态梯度:应用于灰度图,在灰度值变化最剧烈的区域得到的结果数值最大。边缘以高亮区域突出。IplImage* pGradientImage = cvCloneImage(pGrayscaleImage);IplImage* pTempImage = cvCloneImage(pGradientImage);cvMorphologyEx(pGradientImage, pGradientImage, pTempImage, NULL, CV_MOP_GRADIENT, 1);//礼帽:TopHat(src) = src - open(src)//     如果src = dst,则cvMorphologyEx需要临时图像模版。其大小应该和src一样。否则不需要。//     礼帽的效果是:局部亮度极大点被分割出。IplImage* pTopHatImage = cvCloneImage(pGrayscaleImage);cvMorphologyEx(pTopHatImage, pTopHatImage, pTempImage, NULL, CV_MOP_TOPHAT, 1);//黑帽:BlackHat(src) = close(src) - src//     如果src = dst,则cvMorphologyEx需要临时图像模版。其大小应该和src一样。否则不需要。//     黑帽的效果是:黑色“洞”被分割出。IplImage* pBlackHatImage = cvCloneImage(pGrayscaleImage);cvMorphologyEx(pBlackHatImage, pBlackHatImage, pTempImage, NULL, CV_MOP_BLACKHAT, 1);//漫水填充IplImage* pFloodFillImage = cvCloneImage(pBinaryImage);cvFloodFill(pFloodFillImage, cvPoint(0, 0), CV_RGB(255, 255, 255));//高斯模糊,使用高斯模糊的时候允许 in place 也就是src和dst使用同一个图像。IplImage* pGaussImage = cvCloneImage(pSourceImage);cvSmooth(pGaussImage, pGaussImage, CV_GAUSSIAN, 15);//高斯模糊测试IplImage* pGaussTestImage5X5 = cvCreateImage(cvSize(500, 500), 8, 3);cvSet(pGaussTestImage5X5, CV_RGB(0, 0, 0));uchar* pMiddleData = (uchar*)pGaussTestImage5X5->imageData + pGaussTestImage5X5->width / 2 * 3 + pGaussTestImage5X5->height / 2 * pGaussTestImage5X5->widthStep;;pMiddleData[0] = 255;pMiddleData[1] = 255;pMiddleData[2] = 255;IplImage* pGaussTestImage9X9 = cvCloneImage(pGaussTestImage5X5);cvSmooth(pGaussTestImage5X5, pGaussTestImage5X5, CV_GAUSSIAN, 5, 5);cvSmooth(pGaussTestImage5X5, pGaussTestImage5X5, CV_GAUSSIAN, 5, 5);cvSmooth(pGaussTestImage9X9, pGaussTestImage9X9, CV_GAUSSIAN, 9, 9);cvSmooth(pGaussTestImage9X9, pGaussTestImage9X9, CV_GAUSSIAN, 9, 9);//求元素差的绝对值,也就是dst = abs(src1 - src2)IplImage* pSrc1Image = cvLoadImage(szAbsDiffImage1);IplImage* pSrc2Image = cvLoadImage(szAbsDiffImage2);IplImage* pDstDiffImage = cvCloneImage(pSrc1Image);IplImage* pCleanDiffImage = cvCloneImage(pDstDiffImage);//腐蚀后膨胀IplImage* pDirtyDiffImage = cvCloneImage(pDstDiffImage);//膨胀后腐蚀cvAbsDiff(pSrc1Image, pSrc2Image, pDstDiffImage);//先腐蚀,后膨胀cvErode(pDstDiffImage, pCleanDiffImage);cvDilate(pCleanDiffImage, pCleanDiffImage);//先膨胀,后腐蚀cvDilate(pDstDiffImage, pDirtyDiffImage);cvErode(pDirtyDiffImage, pDirtyDiffImage);//分割元素IplImage* pGjlSrc1Image = cvLoadImage(szSplitImage1);IplImage* pGjlSrc2Image = cvLoadImage(szSplitImage2);IplImage* pGjlSrc1GrayscaleImage = cvCreateImage(cvGetSize(pGjlSrc1Image), 8, 1);IplImage* pGjlSrc2GrayscaleImage = cvCreateImage(cvGetSize(pGjlSrc2Image), 8, 1);IplImage* pGjlDiffImage = cvCloneImage(pGjlSrc1GrayscaleImage);//灰度化cvCvtColor(pGjlSrc1Image, pGjlSrc1GrayscaleImage, CV_RGB2GRAY);cvCvtColor(pGjlSrc2Image, pGjlSrc2GrayscaleImage, CV_RGB2GRAY);//去差的绝对值cvAbsDiff(pGjlSrc1GrayscaleImage, pGjlSrc2GrayscaleImage, pGjlDiffImage);//二值图IplImage* pBinaryGjlImage = cvCloneImage(pGjlDiffImage);cvThreshold(pBinaryGjlImage, pBinaryGjlImage, 128, 255, CV_THRESH_BINARY);//二值化图像//执行下开运算。IplImage* pGjlBinaryMopOpenImage = cvCloneImage(pBinaryGjlImage);cvMorphologyEx(pGjlBinaryMopOpenImage, pGjlBinaryMopOpenImage, NULL, NULL, CV_MOP_OPEN, 1);//自适应阈值,二值化IplImage* pAdaptiveBinaryGjlImage = cvCloneImage(pGjlDiffImage);cvAdaptiveThreshold(pAdaptiveBinaryGjlImage, pAdaptiveBinaryGjlImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 3, 5);//执行下开运算IplImage* pGjlAdaptiveBinaryMopOpenImage = cvCloneImage(pAdaptiveBinaryGjlImage);cvMorphologyEx(pGjlAdaptiveBinaryMopOpenImage, pGjlAdaptiveBinaryMopOpenImage, NULL, NULL, CV_MOP_OPEN, 1);//这里开始根据漫水填充法来统计面积最大的区域。CvConnectedComp comp, maxComp;CvPoint ptBeforeFloodFill;ptBeforeFloodFill.x = -1;ptBeforeFloodFill.y = -1;maxComp.area = -1;for (int y = 0; y < pGjlAdaptiveBinaryMopOpenImage->height; ++y){for (int x = 0; x < pGjlAdaptiveBinaryMopOpenImage->width; ++x){uchar* pData = (uchar*)pGjlAdaptiveBinaryMopOpenImage->imageData + x + y * pGjlAdaptiveBinaryMopOpenImage->widthStep;if (pData[0] == 0){cvFloodFill(pGjlAdaptiveBinaryMopOpenImage, cvPoint(x, y), CV_RGB(100, 100, 100), cvScalarAll(0), cvScalarAll(0), &comp);if (maxComp.area < comp.area){if(maxComp.area != -1)cvFloodFill(pGjlAdaptiveBinaryMopOpenImage, cvPoint(ptBeforeFloodFill.x, ptBeforeFloodFill.y), CV_RGB(255, 255, 255));maxComp = comp;ptBeforeFloodFill.x = x;ptBeforeFloodFill.y = y;printf("max area = %.2f\n", maxComp.area);}else{cvFloodFill(pGjlAdaptiveBinaryMopOpenImage, cvPoint(x, y), cvScalarAll(255));}//cvShowImage("自适应然后开运算,骨精灵 - Adaptive Open", pGjlAdaptiveBinaryMopOpenImage);//cvWaitKey(10);}}}//边缘检测IplImage* pEdgesImage = cvCloneImage(pBinaryImage);cvCanny(pEdgesImage, pEdgesImage, 150, 100, 3);if (maxComp.area > 0){cvRectangle(pGjlAdaptiveBinaryMopOpenImage, cvPoint(maxComp.rect.x, maxComp.rect.y),cvPoint(maxComp.rect.x + maxComp.rect.width, maxComp.rect.y + maxComp.rect.height),CV_RGB(0, 0, 0), 3);}//霍夫直线变换CvMemStorage* pMemStorage = cvCreateMemStorage();IplImage* pHoughtLineImage = cvCloneImage(pEdgesImage);CvSeq* lines = cvHoughLines2(pHoughtLineImage, pMemStorage, CV_HOUGH_PROBABILISTIC, 1, 5, 20, 50, 10);for (int i = 0; i < lines->total; ++i){CvPoint* pt = (CvPoint*)cvGetSeqElem(lines, i);cvDrawLine(pHoughtLineImage, pt[0], pt[1], cvScalarAll(255), 3);}//霍夫圆变换 - 这下面的代码耗时太长了,所以屏蔽掉吧。// IplImage* pHoughtCirclesSourceImage = cvCloneImage(pSourceImage);// IplImage* pHoughtCirclesImage = cvCloneImage(pGrayscaleImage);// cvSmooth(pHoughtCirclesImage, pHoughtCirclesImage, CV_GAUSSIAN, 5, 5);// CvSeq* results = cvHoughCircles(pHoughtCirclesImage, pMemStorage, CV_HOUGH_GRADIENT, 2, pHoughtCirclesImage->width / 10);// printf("圆个数 %d\n", results->total);// for (int i = 0; i < results->total; ++i)// {// float* p = (float*)cvGetSeqElem(results, i);// CvPoint pt = cvPoint(cvRound(p[0]), cvRound(p[1]));// cvCircle(pHoughtCirclesSourceImage, pt, cvRound(p[2]), cvScalarAll(0xFF), 5);// cvShowImage("霍夫圆变换 - Hought Circles", pHoughtCirclesSourceImage);// cvWaitKey(300);// }cvShowImage("二值图 - Binary", pBinaryImage);cvShowImage("自适应阈值 - Adaptive", pAdaptiveBinaryImage);cvShowImage("腐蚀 - Erode", pErodeImage);cvShowImage("膨胀 - Dilate", pDilate);cvShowImage("开运算 - Morphology Open", pOpenImage);cvShowImage("闭运算 - Morphology Open", pCLoseImage);cvShowImage("形态梯度 - Morphology Gradient", pGradientImage);cvShowImage("礼帽 - Top Hat", pTopHatImage);cvShowImage("黑帽 - Black Hat", pBlackHatImage);cvShowImage("漫水填充 - Flood Fill", pFloodFillImage);cvShowImage("高斯模糊 - Gauss Smooth", pGaussImage);cvShowImage("高斯模糊测试 - Gauss Smooth Test 5 X 5", pGaussTestImage5X5);cvShowImage("高斯模糊测试 - Gauss Smooth Test 9 X 9", pGaussTestImage9X9);cvShowImage("求原色差的绝对值 - Abs different", pDstDiffImage);cvShowImage("腐蚀后碰着 - Abs different", pCleanDiffImage);cvShowImage("膨胀后腐蚀 - Abs different", pDirtyDiffImage);cvShowImage("差值后的绝对值,骨精灵 - Abs Different", pGjlDiffImage);cvShowImage("阈值二值化过后,骨精灵 - Binary", pBinaryGjlImage);cvShowImage("阈值二值化后开运算,骨精灵 - Mop Open", pGjlBinaryMopOpenImage);cvShowImage("自适应阈值,骨精灵 - Adaptive", pAdaptiveBinaryGjlImage);cvShowImage("自适应然后开运算,骨精灵 - Adaptive Open", pGjlAdaptiveBinaryMopOpenImage);cvShowImage("边缘检测 - Canny", pEdgesImage);cvShowImage("霍夫直线变换 - HoughLines2", pHoughtLineImage);//cvShowImage("霍夫圆变换 - Hought Circles", pHoughtCirclesSourceImage);cvWaitKey();return 0;}