使用opencv识别图像红色区域,并输出红色区域中心点坐标

适用小白,大佬勿喷

个人配置:vs2013 ; opencv 3.0 ;

直接上效果图

注意:右下角的水印把中心点挡住了,要仔细看才能看到

下面是代码:

#include <iostream>
#include<opencv2\opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#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));
	minRGB = (minRGB<b) ? (minRGB) : (b);

	maxRGB = ((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<Vec3b>(x, y)[0];
			G = srcImg.at<Vec3b>(x, y)[1];
			R = srcImg.at<Vec3b>(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<uchar>(x, y) = 255;
			/*cout << H << "," << S << "," << V << endl;*/
		}
	}
	/*imshow("hsv", vec_rgb);*/
	return vec_rgb;

}

void O_x1y1(Mat in, double *x1, double *y1, double *x2, double *y2)

{
	Mat matSrc = in;
	/*Mat matSrc = imread("qwer9.png", 0);*/

	GaussianBlur(matSrc, matSrc, Size(5, 5), 0);//高斯滤波,除噪点

	vector<vector<Point> > contours;//contours的类型,双重的vector

	vector<Vec4i> 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<Moments> mu(contours.size());

	for (int i = 0; i < contours.size(); i++)

	{
		mu[i] = moments(contours[i], false);
	}

	/// 计算矩中心:

	vector<Point2f> 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 ); 

   /*  max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓
    如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种
    如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓 */
   //  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"<<endl;
			cout<<"面积为"<<tmparea<<endl;
			cout<<endl;
			CvRect aRect = cvBoundingRect( contour, 0 );
			//找重心
			{
				CvPoint2D32f center = cvPoint2D32f(0, 0);
				int countOfPoint = 0;
				for(int i = aRect.x; i < aRect.x + aRect.width; ++i){
					for(int j = aRect.y; j < aRect.y + aRect.height; ++j){
						if(*(image->imageData + image->widthStep * j + i) != 0){
							center.x += i;
							center.y += j;
							countOfPoint++;
						}
					}
				}

				center.x /= countOfPoint;
				center.y /= countOfPoint;
				cout<<"重心坐标为x:"<<center.x<<endl;
     		cout<<"重心坐标为y:"<<center.y<<endl;
				cvCircle(dst, cvPoint(center.x, center.y), 5, cvScalar(0, 255), 2);
			}
		}
 // //Threshold the image
 //  cvErode(imgThresholded,imgThresholded);
 //  cvErode(imgThresholded,imgThresholded);
	 //cvErode(imgThresholded,imgThresholded);
	 //cvErode(imgThresholded,imgThresholded);
	 //IplImage* pImg8u=cvCloneImage(imgThresholded);

	 //cvCanny(pImg8u, pImg8u,40, 50, 5);
	 //cvShowImage("pImg8u",pImg8u);
	 //circles=cvHoughCircles(pImg8u,storage,CV_HOUGH_GRADIENT,
		//2,  //最小分辨率,应当>=1
		//pImg8u->height/15,  //该参数是让算法能明显区分的两个不同圆之间的最小距离
		//80,  //用于Canny的边缘阀值上限,下限被置为上限的一半
		//65,  //累加器的阀值
		//25,   //最小圆半径
		//50   //最大圆半径
		//);
 }

	cvShowImage( "contour", dst );
	}

以上这篇使用opencv识别图像红色区域,并输出红色区域中心点坐标就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python-opencv获取二值图像轮廓及中心点坐标的代码

    python-opencv获取二值图像轮廓及中心点坐标代码: groundtruth = cv2.imread(groundtruth_path)[:, :, 0] h1, w1 = groundtruth.shape contours, cnt = cv2.findContours(groundtruth.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) != 1:#轮廓总数 continue M = cv

  • Python Opencv提取图片中某种颜色组成的图形的方法

    主要目标识别图中红色的裂缝,尝试了几种不同的方法,最后发现比较每一点的RGB差值可以很好的解决这个问题,也就是提取图片中的红色相关信息.处理结果如下: 实现的代码如下,注意opencv读入的图片通道顺序是bgr: import cv2 import matplotlib.pyplot as plt imagepath = r'tear/11.jpg' image = cv2.imread(imagepath) height,width,channel = image.shape for i in

  • 通过python改变图片特定区域的颜色详解

    首先让我祭出一张数学王子高斯的照片,这位印在德国马克上的神人有多牛呢? 他是近代数学的奠基人之一,与牛顿, 阿基米德并称顶级三大数学家,随便找一个编程语言的数学库,里面一定有和他名字相关的一堆函数. 开始正文之前,让我们再来膜拜一下19岁的高斯如何用一把圆规和没有刻度的尺子画出正十七边形. 下面我就拿高斯这张肖像画作为示例如何用Python将他帽子的颜色换了. 计算机分析图片不可能像人类的肉眼一样进行观察,再用右脑进行思考,它能识别的只有数字,下面我们从计算机的角度来对图片做一个简单的认知. 机

  • 使用opencv识别图像红色区域,并输出红色区域中心点坐标

    适用小白,大佬勿喷 个人配置:vs2013 ; opencv 3.0 ; 直接上效果图 注意:右下角的水印把中心点挡住了,要仔细看才能看到 下面是代码: #include <iostream> #include<opencv2\opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #define PI 3.1415926 using

  • OpenCV识别图像上的线条轨迹

    如果图片上有线条,图形什么的,人的眼睛可以直接看出来,这是人的直接反应.那么如何让电脑识别呢? 图片在内存中是以二维矩阵的形式存储的,如果是彩图,则是GBR三通道,灰度图则是单通道.本教程用OpenCV去识别图形上的线条,曲线等轨迹. 软件环境:Win7-32, VS2010, OpenCV2.4.9 (1)以灰度图的方式导入图片 Mat src = imread("1.jpg", 0); (2)我的思路:根据图形中的每个像素点的差异去判断,对原图的灰度图做二值化处理,不是线条的区域像

  • Python Opencv实现图像轮廓识别功能

    本文实例为大家分享了python opencv识别图像轮廓的具体代码,供大家参考,具体内容如下 要求:用矩形或者圆形框住图片中的云朵(不要求全部框出) 轮廓检测 Opencv-Python接口中使用cv2.findContours()函数来查找检测物体的轮廓. import cv2 img = cv2.imread('cloud.jpg') # 灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化 ret, binary = cv2.th

  • OpenCV识别提取图像中的水平线与垂直线

    本文实例为大家分享了OpenCV识别提取图像中的水平线与垂直线,供大家参考,具体内容如下 1).原理 图像形态学操作时候,可以通过自定义的结构元素实现结构元素 对输入图像一些对象敏感.另外一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出.通过使用两个最基本的形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像的操作.得到想要的结果. -膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值 -腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值 常见的形状:矩形.园.直线

  • Python+Opencv识别两张相似图片

    在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系. 当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简单几句就说清,所以本文只作基本算法的科普向. 看到一篇博客是介绍这个,但他用的是PIL中的Image实现的,感觉比较麻烦,于是利用Opencv库进行了更简洁化的实现. 相关背景 要识别两张相似图像,我们从感性上来谈是怎么样的一个过程?首先我们会区分这两张相片的类型,例如是风景照,还是人物照.风景照中

  • python+opencv识别图片中的圆形

    本文实例为大家分享了python+opencv识别图片中足球的方法,供大家参考,具体内容如下 先补充下霍夫圆变换的几个参数知识: dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器.上述文字不好理解的话,来看例子吧.例如,如果dp= 1时,累加器和输入图像具有相同的分辨率.如果dp=2,累加器便有输入图像一半那么大的宽度和高度. minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离.这

  • python识别图像并提取文字的实现方法

    前言 python图像识别一般基础到的就是tesseract了,在爬虫中处理验证码广泛使用. 安装 安装教程网上大都差不多,Windows下确实比较麻烦,涉及到各种路径.环境变量甚至与linux不同的路径分隔符,所以这里的安装是基于Centos7. 1. 依赖安装 yum install -y automake autoconf libtool gcc gcc-c++ 2. 安装leptonica Leptonica主要用于图像处理和图像分析 原则上所有的库文件都是可以直接用yum安装的,如果想

  • Python OpenCV处理图像之滤镜和图像运算

    本文实例为大家分享了Python OpenCV处理图像之滤镜和图像运算的具体代码,供大家参考,具体内容如下 0x01. 滤镜 喜欢自拍的人肯定都知道滤镜了,下面代码尝试使用一些简单的滤镜,包括图片的平滑处理.灰度化.二值化等: import cv2.cv as cv image=cv.LoadImage('img/lena.jpg', cv.CV_LOAD_IMAGE_COLOR) #Load the image cv.ShowImage("Original", image) grey

  • Opencv处理图像之轮廓提取

    本文实例为大家分享了Opencv处理图像之轮廓提取,使用cvfindContours对图像进行轮廓检测,供大家参考,具体内容如下 #include<iostream> #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> int main() { IplImage* img = cvLoadImage("E:\\test.bmp",0); IplImage* img

  • python Opencv计算图像相似度过程解析

    这篇文章主要介绍了python Opencv计算图像相似度过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.相关概念 一般我们人区分谁是谁,给物品分类,都是通过各种特征去辨别的,比如黑长直.大白腿.樱桃唇.瓜子脸.王麻子脸上有麻子,隔壁老王和儿子很像,但是儿子下巴涨了一颗痣和他妈一模一样,让你确定这是你儿子. 还有其他物品.什么桌子带腿.镜子反光能在里面倒影出东西,各种各样的特征,我们通过学习.归纳,自然而然能够很快识别分类出新物品.

随机推荐