// 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;
}
*/