文章目录
一、写在前面
1、前言
本文是我的第一篇博客,文章中可能存在些许错误或不足,欢迎提出建议或意见一起讨论。
另OpenCV学习时间较短,对于语言的理解不是很深,有不足之处还望指正。
2、软件版本信息
在 Matlab 2019a & Visual Studio 2017 + OpenCV 中运行都是通过的。
3、出发点
今年下半年一直在学OpenCV + C++。
基于OpenCV的随机性形状生成是受《OpenCV和Visual Studio图像识别应用开发》中文字处理一程序启发,进行了改进与优化,并在Matlab中进行实践。
另希望本文所带来的核心思想或某处代码写法能在设计算法中给予大家启发。
We love Matlab;
We love OpenCV;
二、输出结果展示
因为不支持比较大的GIF所以只能以截图的方式呈现。
无论在Matlab中或者VS 2017中,都是一个代码文件,输出基本顺序为:线条,矩形,三角,圆,文本及升华(后面就知道什么意思了);
1、Matlab中
1.随机线条的生成
2.随机矩形的生成
3.随机文本的生成
这里产生不同内容,不同颜色,不同字体,不同大小的文本;
4.升华
2、OpenCV中
因为大部分内容与Matlab中展示的一样,这里只简单的展示几幅。
1.生成随机线条
2.生成随机矩形
3.升华
三、原理
1、原理总述
其原理简单来说就是随机坐标的生成。对于线条是两个随机坐标的连接;对于矩形是随机生成两个数,然后在二维坐标系中组合成为四个点;三角形状是随机生成三个坐标;至于圆原理类似;文字只是把原来要显示的形状变为字符串进行随机性输出。
而这里所说的随机性,主要有位置、大小和颜色的随机。其背后都是随机性原理。
2、Matlab
Matlab实现的原理主要是在调用一些随机数生成函数和显示函数基础上进行循环输出,即就是显示在图形窗口。
1.rand()函数:产生由在(0, 1)之间均匀分布的随机数组成的数组。
2.unifrnd()函数:生成N阶[a,b]均匀分布数组。
3.text()函数:该函数在图形中指定的位置上显示字符串。
以上是主要调用和使用较多的函数,另有一些函数,使用也较为简单,代码中会注释好。
3、OpenCV
OpenCV实现原理主要是在使用产生随机数的类RNG以及绘制各种形状的API,通过各种API调用随机产生的数据输入作为API参数,从而实现位置,大小和颜色的随机性。
1.RNG(uint64 state):产生随机数,state是起始随机数列的64位值。
至于其它API这里就不详述了,好多博主都讲过,可以查查。
主要有使用到line(直线),rectangle(矩形),ellipse(椭圆),polylines(连接线),fillPoly(多边形),circle(圆),putText(文字)。
四、代码
1、Matlab
clc, close'g all, clear; % m文件运行基操
% 线
axis off;
set(gcf,'menubar','none','toolbar','none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);% 不显示当前figure菜单栏和工具栏。
for i = 1:200
X1 = unifrnd(-0.2,1); Y1 = unifrnd(-0.2,1);
X2 = unifrnd(-0.2,1); Y2 = unifrnd(-0.2,1);
line([X1 X2],[Y1 Y2],'linewidth',3,'color',rand(1,3)); % 将两个点连接起来
pause(0); % 程序暂停0秒
end
hold on; % 保证在同一个窗口上继续产生新的形状
clf; % 用来清除图形的命令,方便画下一个形状
% 矩形
axis off;
set(gcf,'menubar','none','toolbar'ie,'none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);% 不显示当前figure菜单栏和工具栏。
for i = 1:100
X = unifrnd(-0.2,1); Y = unifrnd(-0.2,1);
line([X Y Y X X],[X X Y Y X],'linewidth',3,'color',rand(1,3)); % 将一个矩形连接起来需要五个坐标
pause(0);
end
hold on;
clf;
% 三角形并进行填充
axis off;
set(gcf,'menubar','none','toolbar','none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);
for i = 1:90
X1 = unifrnd(-0.2,1); Y1 = unifrnd(-0.2,1);
X2 = unifrnd(-0j.2,1); Y2 = unifrnd(-0.2,1);
X3 = unifrnd(-0.2,1); Y3 = unifrnd(-0.2,1);
line([X1 X2 X3 X1],[Y1 Y2 Y3 Y1],'linewidth',3,'color',rand(1,3));
axis off;
hold on;
fill([X1 X2 X3 X1],[Y1 Y2 Y3 Y1],rand(1,3));
pause(0);
end
hold on;
clf;
% 圆
set(gcf,'menubar','none','toolbar','none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);
for i = 1:30
x=rand,y=rand,r=rand;
x = x + x *0.6;y = y + y *0.6;
theta=0:2*pi/3600:2*pi;
Circle1=x+r*cos(theta);
Circle2=y+r*sin(theta);
plot(Circle1,Circle2,'color',rand(1,3),'Linewidth',3);
hold on;
fill(Circle1,Circle2,rand(1,3)); % 用随机彩色填充圆形内部,注意这里圆的轮廓和填充色不同
axis([0 2.5 0 2.5]);
axis equal;
axis off;
pause(0);
end
hold on;
clf;
% 文本
TEST(1) = struct('Fontname','Consolas','String','Love'); % 使用一个结构体来保存字体名称和需要随机显示的字符串
TEST(2) = struct('Fontname','Monospaced','String','Passion');
TEST(3) = struct('Fontname','Gigi','String','Supreme');
TEST(4) = struct('Fontname','Chiller','String','Incredible');
TEST(5) = struct('Fontname','Georgia','String','Marvellous');
TEST(6) = struct('Fontname','Harrington','String','Awesome');
TEST(7) = struct('Fontname','Mistral','String','Fantastic');
TEST(8) = struct('Fontname','Pristina','String','Fabulous');
TEST(9) = struct('Fontname','楷体','String','Brilliant');
TEST(10) = struct('Fontname','宋体','String','Amazing');
axis off;
set(gcf,'menubar','none','toolbar','none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);
for k = 1:200
x = unifrnd(-0.2,1);
y = unifrnd(-0.2,1);
text(x,y,TEST(unidrnd(10)).String,...
'fontsize',unifrnd(14,23),...
'fontname',TEST(unidrnd(10)).Fontname,'color',rand(1,3)); % 在text中直接随机调用结构体中的字符串
pause(0);
end
hold on;
clf;
% 生成一个Matlab文本金字塔
axis off;
set(gcf,'menubar','none','toolbar','none','pointer','hand'...
,'unit','centimeters','position',[8,2.5,20,15]);
% 该段代码完全可以使用循环来调用,不过考虑到不同字体有不同的行距和字间距等等,为了美化起见进行了人工调试,以下为期望中较好的,
text(0.3,0.8,'We love Matlab','fontname','Gigi','fontsize',15,'color',rand(1,3));
pause(0.2);
text(0.25,0.75,'We love Matlab','fontname','Monospaced','fontsize',20,'color',rand(1,3));
pause(0.2);
text(0.2,0.7,'We love Matlab','fontname','Consolas','fontsize',25,'color',rand(1,3));
pause(0.2);
text(0.18,0.64,'We love Matlab','fontname','楷体','fontsize',30,'color',rand(1,3));
pause(0.2);
text(0.16,0.55,'We love Matlab','fontname','Georgia','fontsize',35,'color',rand(1,3));
pause(0.2);
text(0.14,0.47,'We love Matlab','fontname','Harrington','fontsize',40,'color',rand(1,3));
pause(0.2);
text(0.12,0.37,'We love Matlab','fontname','Sitka Subheading','fontsize',45,'color',rand(1,3));
pause(0.2);
text(0.1,0.28,'We love Matlab','fontname','Arial','fontsize',50,'color',rand(1,3));
pause(0.2);
text(0.08,0.17,'We love Matlab','fontname','Gadugi','fontsize',55,'color',rand(1,3));
pause(0.2);
text(0.06,0.05,'We love Matlab','fontname','Ebrima','fontsize',60,'color',rand(1,3));
2、OpenCV
因为OpenCV代码较长,300多行,这里只展示其中定义的产生随机颜色的子函数和随机显示文本的子函数。其它放入网盘免费下载链接:
(https://pan.baidu.com/s/1dBL10g34PALzRvrl5LCmyg) 提取码: 7yt4
// 产生随机颜色的子函数
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
// 与 255 作 bit 的 & 运算
return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}
// 随机显示文本的子函数
int Displaying_Random_Text(Mat image, char* window_name, RNG rng)
{
int lineType = 8; // putText的参数:线型
for (int i = 1; i < NUMBER; i++) // 定义在主函数前const int NUMBER = 100;
{
Point org; // 定义point点类用来确定文本的位置;
org.x = rng.uniform(x_1, x_2);
org.y = rng.uniform(y_1, y_2);
putText(image, "Supreme", org,
rng.uniform(0, 8), rng.uniform(0, 100)*0.05 + 0.1,
randomColor(rng), rng.uniform(1, 10), lineType);
// 使用随机数类RNG生成了文本的随机位置,大小,粗细和颜色
imshow(window_name, image);
if (waitKey(DELAY) >= 0)
{
return -1;
}
}
return 0;
}
五、结语
本人也是学习opencv不久,如有错误,请各位大牛指点。目前在学习图像处理算法与机器视觉相关内容,欢迎一起讨论。
QQ:1825628142;
邮箱:suhao_15@163.com;