opencv 边缘检测

// findControl.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>

//#pragma comment(lib,"../lib/opencv_calib3d2413d.lib")
//#pragma comment(lib,"../lib/opencv_contrib2413d.lib")
#pragma comment(lib,"../lib/opencv_core2413d.lib")
//#pragma comment(lib,"../lib/opencv_features2d2413d.lib")
//#pragma comment(lib,"../lib/opencv_flann2413d.lib")
//#pragma comment(lib,"../lib/opencv_gpu2413d.lib")
#pragma comment(lib,"../lib/opencv_highgui2413d.lib")
#pragma comment(lib,"../lib/opencv_imgproc2413d.lib")
//#pragma comment(lib,"../lib/opencv_legacy2413d.lib")
//#pragma comment(lib,"../lib/opencv_ml2413d.lib")
using namespace cv;
using namespace std;
//#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#include <windows.h>
//#include <mmsystem.h>
 
//#pragma comment(lib, "winmm.lib")

/* 
int Otsu(IplImage* src)
{
	int height = src->height;
	int width = src->width;

	float histogram[256] = { 0 };
	for (int i = 0; i < height; i++)
	{
		unsigned char *p = (unsigned char*)src->imageData + src->widthStep*i;
		for (int j = 0; j < width; j++)
			histogram[*p++]++;
	}

	int size = height * width;
	for (int i = 0; i < 256; i++)
		histogram[i] = histogram[i] / size;

	float avgValue = 0;
	for (int i = 0; i < 256; i++)
		avgValue = avgValue + i * histogram[i];  //整幅图像的平均灰度         

	int threshold;
	float maxVariance = 0;
	float w = 0, u = 0;
	for (int i = 0; i < 256; i++)
	{
		w = w + histogram[i];  //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例    
		u = u + i * histogram[i];  // 灰度i 之前的像素(0~i)的平均灰度值: 前景像素的平均灰度值    

		float t = avgValue * w - u;
		float variance = t * t / (w*(1 - w));
		if (variance > maxVariance)
		{
			maxVariance = variance;
			threshold = i;
		}
	}
	return threshold;
}
  //可以使图像膨胀 找边缘
int main(int argc, char** argv)
{
	IplImage *img_in = cvLoadImage("c:\\layer.png");
	cvNamedWindow("img_in");
	cvShowImage("img_in", img_in);

	IplImage *img_gray = cvCreateImage(cvGetSize(img_in), 8, 1);

	int thresh = Otsu(img_in); //求平均灰度的函数
	cvCvtColor(img_in, img_gray, CV_BGR2GRAY);
	cvThreshold(img_gray, img_gray, thresh, 255, CV_THRESH_BINARY_INV);
	 cvDilate(img_gray, img_gray, 0, 2);//可以使图像膨胀,获得更大的连通区域
	cvNamedWindow("img_gray");
	cvShowImage("img_gray", img_gray);

	CvSeq *pContour = NULL;
	CvSeq *pConInner = NULL;
	CvMemStorage *pStorage = NULL;
	pStorage = cvCreateMemStorage(0);
	cvFindContours(img_gray, pStorage, &pContour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
	cvDrawContours(img_gray, pContour, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 2);
	cvNamedWindow("img_gray2");
	cvShowImage("img_gray2", img_gray);

	for (; pContour != NULL; pContour = pContour->h_next)
	{
		CvRect rect = cvBoundingRect(pContour, 0);
		cvRectangle(img_in, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect.y + rect.height), CV_RGB(0, 0, 255));
	}

	cvNamedWindow("img_gray3");
	cvShowImage("img_gray3", img_in);

	cvWaitKey();
	return 0;
}
*/
 

IplImage *g_pGrayImage = NULL;
const char *pstrWindowsBinaryTitle = "二值图";
const char *pstrWindowsOutLineTitle = "轮廓图 ";
CvSeq *g_pcvSeq = NULL;

void on_trackbar(int pos)
{
	// 转为二值图
	IplImage *pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);
	cvThreshold(g_pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY);
	// 显示二值图
	cvShowImage(pstrWindowsBinaryTitle, pBinaryImage);
	cvSaveImage("c:\\Binary.png", pBinaryImage);

	CvMemStorage* cvMStorage = cvCreateMemStorage();
	// 检索轮廓并返回检测到的轮廓的个数
	cvFindContours(pBinaryImage, cvMStorage, &g_pcvSeq);
	 
	IplImage *pOutlineImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 3);
	int _levels = 5;
	cvZero(pOutlineImage);
	//cvDrawContours(pOutlineImage, g_pcvSeq, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), _levels);
	int index = 1;
	system("cls");
	for (; g_pcvSeq != NULL; g_pcvSeq = g_pcvSeq->h_next)
	{
		
		CvRect rect = cvBoundingRect(g_pcvSeq, 0);
	 //	if(rect.height<21 || rect.height>38)
	//		continue; 
		printf("index=%d:x=%d,y=%d,w=%d,h=%d\n", index++,rect.x,rect.y, rect.width, rect.height);
		cvRectangle(pOutlineImage, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect.y + rect.height), CV_RGB(255, 255, 0));
	}
	
	cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);
	cvSaveImage("c:\\Outline.png", pOutlineImage);

	cvReleaseMemStorage(&cvMStorage);
	cvReleaseImage(&pBinaryImage);
	cvReleaseImage(&pOutlineImage);
}

int main(int argc, char** argv)
{
	const char *pstrWindowsSrcTitle = "原图";
	const char *pstrWindowsToolBarName = "二值化";

	// 从文件中加载原图
	IplImage *pSrcImage = cvLoadImage("c:\\1.png", CV_LOAD_IMAGE_UNCHANGED);
	// 显示原图
	cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsSrcTitle, pSrcImage);
	
	// 转为灰度图
	g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
	cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);

	cvNamedWindow("灰度", CV_WINDOW_AUTOSIZE);
	cvShowImage("灰度", g_pGrayImage);
	cvSaveImage("c:\\Gray.png", g_pGrayImage);

	// 创建二值图和轮廓图窗口
	cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
	cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);


	// 滑动条	
	int nThreshold = 0;
	cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);

	on_trackbar(0);

	cvWaitKey(0);

	cvDestroyWindow(pstrWindowsSrcTitle);
	cvDestroyWindow(pstrWindowsBinaryTitle);
	cvDestroyWindow(pstrWindowsOutLineTitle);
	cvReleaseImage(&pSrcImage);
	cvReleaseImage(&g_pGrayImage);
	return 0;
}
 

  
/*  //
int main(int argc, char** argv)
{
	const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";
	const char *pstrWindowsOutLineTitle = "轮廓图(http://blog.csdn.net/MoreWindows)";

	const int IMAGE_WIDTH = 400;
	const int IMAGE_HEIGHT = 200;

	// 创建图像
	IplImage *pSrcImage = cvCreateImage(cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U, 3);
	// 填充成白色
	cvRectangle(pSrcImage, cvPoint(0, 0), cvPoint(pSrcImage->width, pSrcImage->height), CV_RGB(255, 255, 255), CV_FILLED);
	// 画圆
	CvPoint ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);
	int nRadius = 80;
	cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 0), CV_FILLED);
	ptCircleCenter = cvPoint(IMAGE_WIDTH / 4, IMAGE_HEIGHT / 2);
	nRadius = 30;
	cvCircle(pSrcImage, ptCircleCenter, nRadius, CV_RGB(255, 255, 255), CV_FILLED);
	// 画矩形
	CvPoint ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 20, 20);
	CvPoint ptRightBottom = cvPoint(IMAGE_WIDTH - 20, IMAGE_HEIGHT - 20);
	cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(0, 255, 255), CV_FILLED);
	ptLeftTop = cvPoint(IMAGE_WIDTH / 2 + 60, 40);
	ptRightBottom = cvPoint(IMAGE_WIDTH - 60, IMAGE_HEIGHT - 40);
	cvRectangle(pSrcImage, ptLeftTop, ptRightBottom, CV_RGB(255, 255, 255), CV_FILLED);
	// 显示原图
	cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsSrcTitle, pSrcImage);


	// 转为灰度图
	IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
	cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
	// 转为二值图
	IplImage *pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);
	cvThreshold(pGrayImage, pBinaryImage, 250, 255, CV_THRESH_BINARY);


	// 检索轮廓并返回检测到的轮廓的个数
	CvMemStorage *pcvMStorage = cvCreateMemStorage();
	CvSeq *pcvSeq = NULL;
	cvFindContours(pBinaryImage, pcvMStorage, &pcvSeq, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));

	// 画轮廓图
	IplImage *pOutlineImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);
	int nLevels = 5;
	// 填充成白色
	cvRectangle(pOutlineImage, cvPoint(0, 0), cvPoint(pOutlineImage->width, pOutlineImage->height), CV_RGB(255, 255, 255), CV_FILLED);
	cvDrawContours(pOutlineImage, pcvSeq, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), nLevels, 2);
	// 显示轮廓图
	cvNamedWindow(pstrWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);
	cvShowImage(pstrWindowsOutLineTitle, pOutlineImage);


	cvWaitKey(0);

	cvReleaseMemStorage(&pcvMStorage);

	cvDestroyWindow(pstrWindowsSrcTitle);
	cvDestroyWindow(pstrWindowsOutLineTitle);
	cvReleaseImage(&pSrcImage);
	cvReleaseImage(&pGrayImage);
	cvReleaseImage(&pBinaryImage);
	cvReleaseImage(&pOutlineImage);
	return 0;
}
 */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值