OpenCvSharp随机数与绘制文本用法

时间:2024-02-22 13:48:56

目的
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)

 

/// <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)

 

代码实例:

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