
适用小白,大佬勿喷
个人配置:vs2013 ; opencv 3.0 ;
直接上效果图
注意:右下角的水印把中心点挡住了,要仔细看才能看到
下面是代码:
#include#include #include #include #define PI 3.1415926 using namespace cv; using namespace std; void RGB2HSV(double red, double green, double blue, double& hue, double& saturation, double& intensity) { double r, g, b; double h, s, i; double sum; double minRGB, maxRGB; double theta; r = red / 255.0; g = green / 255.0; b = blue / 255.0; minRGB = ((r g) ? (r) : (g)); maxRGB = (maxRGB>b) ? (maxRGB) : (b); sum = r + g + b; i = sum / 3.0; if (i<0.001 || maxRGB - minRGB<0.001) { h = 0.0; s = 0.0; } else { s = 1.0 - 3.0*minRGB / sum; theta = sqrt((r - g)*(r - g) + (r - b)*(g - b)); theta = acos((r - g + r - b)*0.5 / theta); if (b <= g) h = theta; else h = 2 * PI - theta; if (s <= 0.01) h = 0; } hue = (int)(h * 180 / PI); saturation = (int)(s * 100); intensity = (int)(i * 100); } Mat picture_red(Mat input) { Mat frame; Mat srcImg = input; frame = srcImg; waitKey(1); int width = srcImg.cols; int height = srcImg.rows; int x, y; double B = 0.0, G = 0.0, R = 0.0, H = 0.0, S = 0.0, V = 0.0; Mat vec_rgb = Mat::zeros(srcImg.size(), CV_8UC1); for (x = 0; x < height; x++) { for (y = 0; y < width; y++) { B = srcImg.at (x, y)[0]; G = srcImg.at (x, y)[1]; R = srcImg.at (x, y)[2]; RGB2HSV(R, G, B, H, S, V); //红色范围,范围参考的网上。可以自己调 if ((H >= 312 && H <= 360) && (S >= 17 && S <= 100) && (V>18 && V < 100)) vec_rgb.at (x, y) = 255; } } return vec_rgb; } void O_x1y1(Mat in, double *x1, double *y1, double *x2, double *y2) { Mat matSrc = in; GaussianBlur(matSrc, matSrc, Size(5, 5), 0);//高斯滤波,除噪点 vector > contours;//contours的类型,双重的vector vector hierarchy;//Vec4i是指每一个vector元素中有四个int型数据。 //阈值 threshold(matSrc, matSrc, 100, 255, THRESH_BINARY);//图像二值化 //寻找轮廓,这里注意,findContours的输入参数要求是二值图像,二值图像的来源大致有两种,第一种用threshold,第二种用canny findContours(matSrc.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); /// 计算矩 vector mu(contours.size()); for (int i = 0; i < contours.size(); i++) { mu[i] = moments(contours[i], false); } /// 计算矩中心: vector mc(contours.size()); for (int i = 0; i < contours.size(); i++) { mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00); } /// 绘制轮廓 Mat drawing = Mat::zeros(matSrc.size(), CV_8UC1); for (int i = 0; i < contours.size(); i++) { Scalar color = Scalar(255); //drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());//绘制轮廓函数 circle(drawing, mc[i], 4, color, -1, 8, 0); } *x1 = mc[0].x; *y1 = mc[0].y; *x2 = mc[contours.size()-1].x; *y2 = mc[contours.size() - 1].y; imshow("outImage", drawing); } int main() { double xx1, yy1, xx2, yy2; double x1, y1, x2, y2; Mat matSrc = imread("qwer4.png"); Mat middle = picture_red(matSrc); O_x1y1(middle, &xx1, &yy1, &xx2, &yy2); x1 = xx1; y1 = yy1; x2 = xx2; y2 = yy2; imshow("原图", matSrc); imshow("red", picture_red(matSrc)); cout << "红点:" << x1 << ", " << y1 << "; " << "红点1:" << x2 << ", " << y2 << endl; waitKey(); return 0; }
如有不足,望指点!
补充知识:opencv 识别网球 ,或者绿色的小球 输出重心坐标
我就废话不多说了,大家还是直接看代码吧!
void image_process(IplImage *image)
{
int iLowH =26;
int iHighH = 69;
int iLowS = 42;
int iHighS = 206;
int iLowV = 0;
int iHighV = 198;
CvMemStorage* storage2 = cvCreateMemStorage();
CvSeq* contour3 = NULL;
CvMoments moments;
CvMat *region;
CvPoint pt1,pt2;
double m00 = 0, m10, m01, mu20, mu11, mu02, inv_m00;
double a, b, c;
int xc, yc;
CvMemStorage* storage = cvCreateMemStorage();
CvSeq * circles=NULL;
// Circle cir[6];
CvPoint P0;
CvPoint CenterPoint;
// cvNamedWindow("win1");
//cvShowImage("win1",image);
//cvNamedWindow("image",CV_WINDOW_AUTOSIZE);//用于显示图像的窗口
//cvNamedWindow("hsv",CV_WINDOW_AUTOSIZE);
//cvNamedWindow("saturation",CV_WINDOW_AUTOSIZE);
//cvNamedWindow("value",CV_WINDOW_AUTOSIZE);
//cvNamedWindow("pImg8u",1);
IplImage *hsv=cvCreateImage(cvGetSize(image),8,3);//给hsv色系的图像申请空间
IplImage *hue=cvCreateImage(cvGetSize(image),8,1); //色调
IplImage *saturation=cvCreateImage(cvGetSize(image),8,1);//饱和度
IplImage *value=cvCreateImage(cvGetSize(image),8,1);//亮度
IplImage *imgThresholded=cvCreateImage(cvGetSize(hue),8,1);
cvNamedWindow("yuan",1);
cvCvtColor(image,hsv,CV_BGR2HSV);//将RGB色系转为HSV色系
cvShowImage("yuan",image);
//cvShowImage("hsv",hsv);
cvSplit(hsv, hue, 0, 0, 0 );//分离三个通道
cvSplit(hsv, 0, saturation, 0, 0 );
cvSplit(hsv, 0, 0, value, 0 );
int value_1=0;
cvInRangeS(
hsv,
cvScalar(iLowH, iLowS, iLowV),
cvScalar(iHighH, iHighS, iHighV),
imgThresholded
);
cvNamedWindow("imgThresholded",1);
cvShowImage("imgThresholded",imgThresholded);
IplImage*pContourImg= cvCreateImage( cvGetSize(image), 8, 1 );
cvCopy(imgThresholded,pContourImg);
cvNamedWindow("pContourImg",1);
cvShowImage("pContourImg",pContourImg);
IplImage* dst = cvCreateImage( cvGetSize(image), 8, 3 );
CvMemStorage* storage3 = cvCreateMemStorage(0);
CvSeq* contour = 0;
// 提取轮廓
int contour_num = cvFindContours(pContourImg, storage3, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
cvZero(dst); // 清空数组
CvSeq *_contour = contour;
double maxarea = 100;
double minarea = 10;
int m = 0;
for( ; contour != 0; contour = contour->h_next )
{
double tmparea = fabs(cvContourArea(contour));
if(tmparea < minarea)
{
cvSeqRemove(contour, 0); // 删除面积小于设定值的轮廓
continue;
}
CvRect aRect = cvBoundingRect( contour, 0 );
if ((aRect.width/aRect.height)<1)
{
cvSeqRemove(contour, 0); //删除宽高比例小于设定值的轮廓
continue;
}
if(tmparea > maxarea)
{
maxarea = tmparea;
}
m++;
// 创建一个色彩值
// CvScalar color = CV_RGB( 0, 0, 255 );
// cvDrawContours(dst, contour, color, color, 0, 1, 8); //绘制外部和内部的轮廓
}
contour = _contour;
int count = 0; double tmparea=0;
for(; contour != 0; contour = contour->h_next)
{
count++;
tmparea = fabs(cvContourArea(contour));
if (tmparea >= maxarea)
{
CvScalar color = CV_RGB( 0, 255, 0);
cvDrawContours(dst, contour, color, color, -1, 1, 8);
cout<<"222"<imageData + image->widthStep * j + i) != 0){
center.x += i;
center.y += j;
countOfPoint++;
}
}
}
center.x /= countOfPoint;
center.y /= countOfPoint;
cout<<"重心坐标为x:"<=1
//pImg8u->height/15, //该参数是让算法能明显区分的两个不同圆之间的最小距离
//80, //用于Canny的边缘阀值上限,下限被置为上限的一半
//65, //累加器的阀值
//25, //最小圆半径
//50 //最大圆半径
//);
}
cvShowImage( "contour", dst );
}
以上这篇使用opencv识别图像红色区域,并输出红色区域中心点坐标就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持考高分网。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)