1.基本绘图

(cv :: Point)定义图像中的2D点

Point pt;
pt.x = 10;
pt.y = 8;

(cv :: Scalar)用于传递像素值

如果我们被要求一个颜色参数,我们给出:
Scalar( a, b, c )
我们将定义一个BGR颜色,如:Blue = a,Green = b和Red = c

(cv :: setTo)将所有或部分数组元素设置为指定的值。
Mat& setTo(InputArray value, InputArray mask=noArray());
  • value指定的标量转换为实际的数组类型。
  • mask与*this相同大小的操作掩码。它的非零元素表示哪个矩阵
(cv :: create)创建一个图像矩阵的矩阵体
void create(int rows, int cols, int type);

函数功能:
1)如果需要,分配新的数组数据
2)创建一个图像矩阵的矩阵体

  • rows:新的行数。
  • cols:新的列数。
  • type:新的矩阵类型。

1.1.(cv :: line)直线

CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
                     int thickness = 1, int lineType = LINE_8, int shift = 0);
  • img:图像。
  • pt1:线段的第一个点。
  • pt2:线段的第二个点。
  • color:线条颜色。
  • thickness:线的厚度。
  • lineType:行类型。看到#线型。
  • shift:点坐标的小数位数。

1.2.(cv :: rectangle)矩形

CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2,
                          const Scalar& color, int thickness = 1,
                          int lineType = LINE_8, int shift = 0);
  • img:图像。
  • pt1:矩形的顶点。
  • pt2:与pt1相对的矩形顶点。
  • color:矩形颜色或亮度(灰度图像)。
  • thickness:组成矩形的线条的厚度。负值,比如#FILLED,意味着函数必须画一个填充矩形。
  • lineType:行类型。看到#线型
  • shift:点坐标的小数位数。
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
#define w 300
int main()
{
    //创建一个白色背景图像 creat a white background image
    Mat img;
    img.create(w, w, CV_8UC3);  //画直线
    img.setTo(Scalar(255, 255, 255)); //背景色设置为白色
    //型线图,线道 draw lines
    line(img, Point(w / 4, w / 4), Point(3 * w / 4, w / 4), Scalar(255, 0, 0));
    line(img, Point(w / 6, w / 2), Point(5 * w / 6, w / 2), Scalar(0, 255, 0));
    line(img, Point(w / 10, 3 * w / 4), Point(9 * w / 10, 3 * w / 4), Scalar(0, 0, 255)); 
    //画矩形 draw rectangle
    rectangle(img, Point(w / 12, w / 12), Point(11 * w / 12, 9 * w / 10), Scalar(200, 200, 100));

<span >imshow</span><span >(</span><span >"line and rectangle"</span><span >,</span> img<span >)</span><span >;</span>
<span >waitKey</span><span >(</span><span >0</span><span >)</span><span >;</span>

}

1.3.(cv :: circle)绘制具有给定圆心和半径的简单圆或填充圆

CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius,
                       const Scalar& color, int thickness = 1,
                       int lineType = LINE_8, int shift = 0);
  • img:画圆的图像。
  • center:圆心。
  • radius:圆的半径。
  • color:圆形颜色。
  • thickness:圆形轮廓的厚度,如果是正的。负值,比如#FILLED,意思是画一个圆。
  • lineType:圆边界的类型。看到#线型。
  • shift:中心坐标和半径值的小数位数。

1.4.(cv :: ellipse)绘制简单或粗的椭圆弧或填充椭圆扇形

绘图代码使用一般参数形式。采用分段线性曲线逼近椭圆弧边界。如果您需要更多的椭圆渲染控制,您可以使用#ellipse2Poly,然后用#polylines渲染,或者用#fillPoly填充。

CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes,
                        double angle, double startAngle, double endAngle,
                        const Scalar& color, int thickness = 1,
                        int lineType = LINE_8, int shift = 0);
  • img:图像。
  • center:椭圆的中心。椭圆主轴大小的一半。
  • angle:椭圆旋转角度。
  • startAngle:椭圆弧的起始角度。
  • endAngle:椭圆圆弧的结束角。
  • color:椭圆颜色。
  • thickness:椭圆轮廓的厚度,如果为正。否则,这表示一个填充椭圆扇形将被绘制。
  • lineType:椭圆边界的类型。看到#线型
  • shift:中心坐标和轴值的小数位数。
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
#define w 400
int main()
{
    //创建一个白色背景图像 creat a white background image
    Mat img;
    img.create(w, w, CV_8UC3);  //画直线
    img.setTo(Scalar(255, 255, 255)); //背景色设置为白色
    //型线图,线道 draw lines 
    line(img, Point(w / 4, w / 14), Point(3 * w / 4, w / 14), Scalar(255, 0, 0));
    line(img, Point(w / 6, w / 5), Point(5 * w / 6, w / 5), Scalar(0, 255, 0));
    line(img, Point(w / 10, 3 * w / 8), Point(9 * w / 10, 3 * w / 8), Scalar(0, 0, 255)); 
    //画矩形 draw rectangle    
    rectangle(img, Point(w / 27, w / 27), Point(11 * w / 12, 9 * w / 10), Scalar(200, 200, 100));
    //圆 circle  
    circle(img, Point(w / 2, w / 1.5), 50, Scalar(255, 0, 0));
    //椭圆 ellipse    
    ellipse(img, Point(w / 2, w / 1.5), Size(100, 50), 0, 0, 360, Scalar(0, 255, 0));

<span >imshow</span><span >(</span><span >"line and rectangle"</span><span >,</span> img<span >)</span><span >;</span>
<span >waitKey</span><span >(</span><span >0</span><span >)</span><span >;</span>

}

执行结果:

opencv blob detect 坐标排序_数位

1.5.(cv :: fillPoly)填充一个或多个多边形边界的区域

填充由多个多边形轮廓包围的区域。函数可以填充复杂的区域,例如,有孔的区域,具有自交点的轮廓(它们的一些
部件),等等。

CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
                           const Scalar& color, int lineType = LINE_8, int shift = 0,
                           Point offset = Point() );

img:图像。
pts:多边形数组,其中每个多边形都表示为一个点数组。
lineType:多边形边界的类型。看到#线型
shift:顶点坐标中的小数位数。
offset:等高线所有点的可选偏移量。
Scalar& color:多边形颜色。

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
#define w 400
int main()
{
    //创建一个白色背景图像 creat a white background image
    Mat img;
    img.create(w, w, CV_8UC3);  //画直线
    img.setTo(Scalar(255, 255, 255)); //背景色设置为白色
    //画矩形 draw rectangle    
    rectangle(img, Point(w / 27, w / 27), Point(11 * w / 12, 9 * w / 10), Scalar(200, 200, 100));

Point rook_points<span >[</span><span >1</span><span >]</span><span >[</span><span >20</span><span >]</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >0</span><span >]</span> <span >=</span> <span >Point</span><span >(</span>w <span >/</span> <span >4</span><span >,</span> <span >7</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >1</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >3</span> <span >*</span> w <span >/</span> <span >4</span><span >,</span> <span >7</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >2</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >3</span> <span >*</span> w <span >/</span> <span >4</span><span >,</span> <span >13</span> <span >*</span> w <span >/</span> <span >16</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >3</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >11</span> <span >*</span> w <span >/</span> <span >16</span><span >,</span> <span >13</span> <span >*</span> w <span >/</span> <span >16</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >4</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >19</span> <span >*</span> w <span >/</span> <span >32</span><span >,</span> <span >3</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >5</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >3</span> <span >*</span> w <span >/</span> <span >4</span><span >,</span> <span >3</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >6</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >3</span> <span >*</span> w <span >/</span> <span >4</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >7</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >26</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >8</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >26</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >4</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >9</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >22</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >4</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >10</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >22</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >11</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >18</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >12</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >18</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >4</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >13</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >14</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >4</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >14</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >14</span> <span >*</span> w <span >/</span> <span >40</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >15</span><span >]</span> <span >=</span> <span >Point</span><span >(</span>w <span >/</span> <span >4</span><span >,</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >16</span><span >]</span> <span >=</span> <span >Point</span><span >(</span>w <span >/</span> <span >4</span><span >,</span> <span >3</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >17</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >13</span> <span >*</span> w <span >/</span> <span >32</span><span >,</span> <span >3</span> <span >*</span> w <span >/</span> <span >8</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >18</span><span >]</span> <span >=</span> <span >Point</span><span >(</span><span >5</span> <span >*</span> w <span >/</span> <span >16</span><span >,</span> <span >13</span> <span >*</span> w <span >/</span> <span >16</span><span >)</span><span >;</span>
rook_points<span >[</span><span >0</span><span >]</span><span >[</span><span >19</span><span >]</span> <span >=</span> <span >Point</span><span >(</span>w <span >/</span> <span >4</span><span >,</span> <span >13</span> <span >*</span> w <span >/</span> <span >16</span><span >)</span><span >;</span>
<span >const</span> Point<span >*</span> ppt<span >[</span><span >1</span><span >]</span> <span >=</span> <span >{<!-- --></span> rook_points<span >[</span><span >0</span><span >]</span> <span >}</span><span >;</span>   
<span >int</span> npt<span >[</span><span >]</span> <span >=</span> <span >{<!-- --></span> <span >20</span> <span >}</span><span >;</span> 
<span >//画多边形 draw polygon     </span>
<span >fillPoly</span><span >(</span>img<span >,</span> ppt<span >,</span> npt<span >,</span> <span >1</span><span >,</span> <span >Scalar</span><span >(</span><span >255</span><span >,</span> <span >0</span><span >,</span> <span >0</span><span >)</span><span >)</span><span >;</span>  
<span >imshow</span><span >(</span><span >"line and rectangle"</span><span >,</span> img<span >)</span><span >;</span>
<span >waitKey</span><span >(</span><span >0</span><span >)</span><span >;</span>

}

执行结果:

opencv blob detect 坐标排序_数位_02

2.Blob分析

2.1.(cv :: drawKeypoints)绘制关键点。

CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage,
                               const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );

image:源图像。
keypoints:来自源图像的关键点。输出图像。对象中绘制的内容取决于标志值。输出图像。见下面可能的标志位值。
color:关键点的颜色。
flags:标记设置绘图特性。可能的标志位值由DrawMatchesFlags。详见drawMatches。

2.2.SimpleBlobDetector的使用

class CV_EXPORTS_W SimpleBlobDetector : public Feature2D
{
public:
  struct CV_EXPORTS_W_SIMPLE Params
  {
      CV_WRAP Params();
      CV_PROP_RW float thresholdStep;
      CV_PROP_RW float minThreshold;
      CV_PROP_RW float maxThreshold;
      CV_PROP_RW size_t minRepeatability;
      CV_PROP_RW float minDistBetweenBlobs;

  CV_PROP_RW <span >bool</span> filterByColor<span >;</span>
  CV_PROP_RW uchar blobColor<span >;</span>

  CV_PROP_RW <span >bool</span> filterByArea<span >;</span>
  CV_PROP_RW <span >float</span> minArea<span >,</span> maxArea<span >;</span>

  CV_PROP_RW <span >bool</span> filterByCircularity<span >;</span>
  CV_PROP_RW <span >float</span> minCircularity<span >,</span> maxCircularity<span >;</span>

  CV_PROP_RW <span >bool</span> filterByInertia<span >;</span>
  CV_PROP_RW <span >float</span> minInertiaRatio<span >,</span> maxInertiaRatio<span >;</span>

  CV_PROP_RW <span >bool</span> filterByConvexity<span >;</span>
  CV_PROP_RW <span >float</span> minConvexity<span >,</span> maxConvexity<span >;</span>

  <span >void</span> <span >read</span><span >(</span> <span >const</span> FileNode<span >&</span> fn <span >)</span><span >;</span>
  <span >void</span> <span >write</span><span >(</span> FileStorage<span >&</span> fs <span >)</span> <span >const</span><span >;</span>

};

CV_WRAP static Ptr<SimpleBlobDetector>
create(const SimpleBlobDetector::Params &parameters = SimpleBlobDetector::Params());
CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
};

  1. thresholdStep、minThreshold、maxThreshold:阈值控制。
  2. findContours:通过findContours从每个二值图像中提取连接组件并计算它们中心。
  3. minDistBetweenBlobs:组中心从几个二值图像的坐标。闭合中心形成一个基团对应一个blob,由minDistBetweenBlobs参数控制。
  4. filterBy:从组中,估计最终的圆心和它们的半径,并返回位置和大小的要点。

这个类对返回的blob执行多次过滤。你应该设置filterBy*为true/false 打开/关闭相应的过滤。可用过滤:

  1. blobColor:该滤波器将一个斑点中心的二值图像的强度与球色。如果它们不同,则过滤掉集合。使用blobColor = 0提取黑色斑点和blobColor = 255提取光斑点。
  2. minArea、maxArea:像素面积大小控制;提取的blobs有一个区域之间的minArea(包括)和maxArea(不包括)。
  3. minCircularity、maxCircularity:(\f$ frac{4*\pi*Area}{perimeter * perimeter}\f$)介于minCircularity(含)和
    maxCircularity(独家)。
  4. mininertiratio、maxinertiratio:最小惯性与最大惯性的比率;mininertiratio(含)和maxinertiratio(不含)之间。
  5. minConvexity、maxConvexity:凸形控制;提取的斑点之间有凹凸(斑点凸包的面积/面积)minConvexity(包括)和maxConvexity(不包括)。参数的默认值被调整为提取黑色的圆形斑点。

2.3.斑点检测

#include <opencv2/highgui.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main() {
Mat img = imread("…/data/test5.jpg", IMREAD_GRAYSCALE);
SimpleBlobDetector::Params params;
//阈值控制
params.minThreshold = 10;
params.maxThreshold = 200;
//像素面积大小控制
params.filterByArea = true;
params.minArea = 1000;
//形状(凸)
params.filterByCircularity = false;
params.minCircularity = 0.7;
//形状(凹)
params.filterByConvexity = true;
params.minConvexity = 0.9;
//形状(园)
params.filterByInertia = false;
params.minInertiaRatio = 0.5;

Ptr<span ><</span>SimpleBlobDetector<span >></span> detector <span >=</span> SimpleBlobDetector<span >::</span><span >create</span><span >(</span><span >)</span><span >;</span>
vector<span ><</span>KeyPoint<span >></span> keypoints<span >;</span>
detector<span >-</span><span >></span><span >detect</span><span >(</span>img<span >,</span> keypoints<span >)</span><span >;</span>
Mat img_with_keypoints<span >;</span>
<span >drawKeypoints</span><span >(</span>img<span >,</span> keypoints<span >,</span> img_with_keypoints<span >,</span> <span >Scalar</span><span >(</span><span >0</span><span >,</span> <span >0</span><span >,</span> <span >255</span><span >)</span><span >,</span> DrawMatchesFlags<span >::</span>DRAW_RICH_KEYPOINTS<span >)</span><span >;</span>
<span >imshow</span><span >(</span><span >"keypoints"</span><span >,</span> img_with_keypoints<span >)</span><span >;</span>
<span >waitKey</span><span >(</span><span >0</span><span >)</span><span >;</span>
<span >return</span> <span >0</span><span >;</span>

}

执行结果:

opencv blob detect 坐标排序_opencv_03

3.(cv :: putText)在图像上显示文本

CV_EXPORTS_W void putText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );
  • img :输入图像。
  • text :显示字符串。
  • org:第一个字符左下角的坐标。
  • font :字体结构初始化。
  • color :文本的字体颜色。
    CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体。
    CV_FONT_HERSHEY_PLAIN - 小号无衬线字体。
    CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体比 CV_FONT_HERSHEY_SIMPLEX 更复杂)
    CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体。
    CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比 CV_FONT_HERSHEY_COMPLEX更复杂)
    CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本。
    CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体。
    CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比 CV_FONT_HERSHEY_SCRIPT_SIMPLEX 更复杂
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
	Mat img;
	img = imread("./image/test2.jpg", 1);
	namedWindow("显示效果图", WND_PROP_AUTOSIZE);
	putText(img, "Hello ", Point(50, 60), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 4, 8);
	imshow("显示效果图", img);
	waitKey(0);
	return 0;

}

执行结果:

opencv blob detect 坐标排序_数位_04