OpenCvSharp学习笔记10--随机数和绘制文本(RNG、PutText、GetTextSize)

目的

RNG函数使用

PutText函数使用

GetTextSize函数使用

RNG随机数生成

生成伪随机数。注意,当初始的state一样时,每次生成的随机数序列是一样的。

PutText绘制文本

函数说明:将文本绘制到图像上(不支持中文)。无绘制的文本用问号代替。

//函数原型
void PutText(InputOutputArray img,
    string text,
    Point org,
    HersheyFonts fontFace,
    double fontScale,
    Scalar color,
    int thickness = 1,
    LineTypes lineType = LineTypes.Link8,
    bool bottomLeftOrigin = false)
参数 说明
InputOutputArray img 待绘制文本的图像
string text 待绘制的文本内容
Point org 文本插入点。默认是左下角。
HersheyFonts fontFace 文本字体
double fontScale 字体比例因子
Scalar color 文本颜色
int thickness 文本线宽
LineTypes lineType 文本线型
bool bottomLeftOrigin 图像原点是否左下角。默认是false,为左上角。为true时,显示的文字是倒影
/// <summary>
/// 绘制文本
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Display_Big_End(Mat image, string winName)
{
    var text = "OpenCvSharp";
    double fontScale = 2D;
    int thickness = 4;

    //图像中心点
    Point center = new Point(image.Width >> 1, image.Height >> 1);

    Size textSize = Cv2.GetTextSize(text, HersheyFonts.HersheyComplex, fontScale, thickness, out int baseLine);
    //文字在图像的中心
    Point org = new Point((image.Width - textSize.Width) / 2, (image.Height + textSize.Height - baseLine) / 2);

    Mat image2;
    for (int i = 0; i < 255; i += 2)
    {
        image2 = image - Scalar.All(i);

        //bottomLeftOrign=false
        Cv2.PutText(image2, text, org, HersheyFonts.HersheyComplex, fontScale, new Scalar(i, i, 255), thickness, lineType, false); 

        //文本插入点
        Cv2.Circle(image2, org, 3, Scalar.White, -1);

        //图片中心点
        Cv2.Circle(image2, center, 5, Scalar.Green, -1);

        //文本的宽高
        Cv2.Rectangle(image2, org, new Point(org.X + textSize.Width, org.Y - textSize.Height), Scalar.Red);
        
        //基线位置
        Cv2.Line(image2, new Point(org.X, org.Y + baseLine), new Point(org.X + textSize.Width, org.Y + baseLine), Scalar.White, 1);

        //bottomLeftOrign = true,以基线为镜
        var newOrg = new Point(org.X, org.Y + baseLine * 2);
        Cv2.PutText(image2, text, newOrg, HersheyFonts.HersheyComplex, fontScale, new Scalar(i, i, 255), thickness, lineType, true);
        //新的文本插入点
        Cv2.Circle(image2, newOrg, 3, Scalar.White, -1);

        Cv2.ImShow(winName, image2);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

上面文字会正常插入,红色框为GetTextSize获取的文本大小,左边白点为插入点。白色线为基线。

 GetTextSize获取绘制文本的大小

函数说明:计算绘制文本的宽、高和基线y轴偏移。

//函数原型
Size GetTextSize(string text,
    HersheyFonts fontFace,
    double fontScale,
    int thickness,
    out int baseLine)
参数 说明
string text 待计算大小的文本内容
HersheyFonts fontFace 文本字体
double fontScale 字体比例因子
int thickness 文字粗细
out int baseLine 底部文本相对于插入点的y轴偏移量。

源码示例

int Width = 600;
int NUMBER = 50;
int DELAY = 50;
LineTypes lineType = LineTypes.Link8;

public void Run(ParamBase paramBase)
{
    //注意初始值一样,每次生成的随机数序列是一样的
    //RNG rng = new RNG(0xFFFFFFFF);
    RNG rng = new RNG((ulong)DateTime.Now.Ticks);            
    var winName = "Random generator and text with OpenCV";
    try
    {
        using (Mat image = Mat.Zeros(Width, Width, MatType.CV_8UC3))
        {
            int c = 0;
            //随机画线
            c = Drawing_Random_Lines(image.Clone(), winName, rng);
            if (c != 0) return;
            //随机绘制或填充矩形
            c = Drawing_Random_Rectangels(image.Clone(), winName, rng);
            if (c != 0) return;

            //随机绘制或填充椭圆轮廓
            c = Drawing_Random_Ellipses(image.Clone(), winName, rng);
            if (c != 0) return;

            //随机显示文本
            c = Drawing_Random_Text(image.Clone(), winName, rng);
            if (c != 0) return;

            //测试PutText或GetTextSize函数
            c = Display_Big_End(image, winName);
        }
    }
    catch { }
    finally
    {
        Cv2.DestroyAllWindows();
    }

}

/// <summary>
/// 绘制文本
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Display_Big_End(Mat image, string winName)
{
    var text = "OpenCvSharp";
    double fontScale = 2D;
    int thickness = 4;

    //图像中心点
    Point center = new Point(image.Width >> 1, image.Height >> 1);

    Size textSize = Cv2.GetTextSize(text, HersheyFonts.HersheyComplex, fontScale, thickness, out int baseLine);
    //文字在图像的中心
    Point org = new Point((image.Width - textSize.Width) / 2, (image.Height + textSize.Height - baseLine) / 2);

    Mat image2;
    for (int i = 0; i < 255; i += 2)
    {
        image2 = image - Scalar.All(i);

        //bottomLeftOrign=false
        Cv2.PutText(image2, text, org, HersheyFonts.HersheyComplex, fontScale, new Scalar(i, i, 255), thickness, lineType, false); 

        //文本插入点
        Cv2.Circle(image2, org, 3, Scalar.White, -1);

        //图片中心点
        Cv2.Circle(image2, center, 5, Scalar.Green, -1);

        //文本的宽高
        Cv2.Rectangle(image2, org, new Point(org.X + textSize.Width, org.Y - textSize.Height), Scalar.Red);
        
        //基线位置
        Cv2.Line(image2, new Point(org.X, org.Y + baseLine), new Point(org.X + textSize.Width, org.Y + baseLine), Scalar.White, 1);

        //bottomLeftOrign = true,以基线为镜
        var newOrg = new Point(org.X, org.Y + baseLine * 2);
        Cv2.PutText(image2, text, newOrg, HersheyFonts.HersheyComplex, fontScale, new Scalar(i, i, 255), thickness, lineType, true);
        //新的文本插入点
        Cv2.Circle(image2, newOrg, 3, Scalar.White, -1);

        Cv2.ImShow(winName, image2);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

/// <summary>
/// 随机绘制文本
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Drawing_Random_Text(Mat image, string winName, RNG rng)
{
    Point org = new Point();
    for (int i = 0; i < NUMBER; i++)
    {
        org.X = rng.Uniform(0, Width);
        org.Y = rng.Uniform(0, Width);
        Cv2.PutText(image, "Testing text rendering", org,
                    (HersheyFonts)rng.Uniform(0, 8),
                    rng.Uniform(0, 100) * 0.05 + 0.1,
                    randomColor(rng),
                    rng.Uniform(0, 10),
                    lineType);
        Cv2.ImShow(winName, image);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

/// <summary>
/// 返回随机颜色
/// </summary>
/// <param name="rng"></param>
/// <returns></returns>
Scalar randomColor(RNG rng)
{
    //Scalar.RandomColor();
    uint iColor = (uint)rng;
    return new Scalar(iColor & 255, (iColor >> 8) & 255, (iColor >> 16) & 255);

}
/// <summary>
/// 随机画椭圆弧
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Drawing_Random_Ellipses(Mat image, string winName, RNG rng)
{
    Point center = new Point();
    Size axes = new Size();
    for (int i = 0; i < NUMBER; i++)
    {
        center.X = rng.Uniform(0, Width);
        center.Y = rng.Uniform(0, Width);
        axes.Width = rng.Uniform(0, Width);
        axes.Height = rng.Uniform(0, Width);
        Cv2.Ellipse(image, center, axes, rng.Uniform(0, 361), rng.Uniform(0, 361), rng.Uniform(0, 361), randomColor(rng), RandomThickness(rng), lineType);
        Cv2.ImShow(winName, image);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

/// <summary>
/// 随机画矩形
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Drawing_Random_Rectangels(Mat image, string winName, RNG rng)
{
    Point pt1 = new Point();
    Point pt2 = new Point();
    for (int i = 0; i < NUMBER; i++)
    {
        pt1.X = rng.Uniform(0, Width);
        pt1.Y = rng.Uniform(0, Width);
        pt2.X = rng.Uniform(0, Width);
        pt2.Y = rng.Uniform(0, Width);
        
        Cv2.Rectangle(image, pt1, pt2, randomColor(rng), RandomThickness(rng), lineType);
        Cv2.ImShow(winName, image);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

/// <summary>
/// 获取颜色线宽
/// </summary>
/// <param name="rng"></param>
/// <returns></returns>
int RandomThickness(RNG rng)
{
    int thickness = rng.Uniform(-9, 10);
    if (thickness == 0) thickness = 1;
    return thickness;
}

/// <summary>
/// 随机画线
/// </summary>
/// <param name="image"></param>
/// <param name="winName"></param>
/// <param name="rng"></param>
/// <returns></returns>
int Drawing_Random_Lines(Mat image, string winName, RNG rng)
{
    Point pt1 = new Point();
    Point pt2 = new Point();
    for (int i = 0; i < NUMBER; i++)
    {
        pt1.X = rng.Uniform(0, Width);
        pt1.Y = rng.Uniform(0, Width);
        pt2.X = rng.Uniform(0, Width);
        pt2.Y = rng.Uniform(0, Width);
        Cv2.Line(image, pt1, pt2, randomColor(rng), rng.Uniform(1, 10), lineType);
        Cv2.ImShow(winName, image);
        if (Cv2.WaitKey(DELAY) >= 0) return -1;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/TyroneKing/article/details/129813307