这次整理的内容是:几何形状绘制和ROI(region of interest)感兴趣区域提取。
RNG rng; //一个随机数对象
image = Scalar(0, 0, 0);
int height = image.rows;
int width = image.cols;
for (int i = 0; i < 100000; i++)
{
int x1 = rng.uniform(0, width); //rng.uniform(a, b)生成[a, b)之间的随机数,包含a,但是不包含b
int y1 = rng.uniform(0, height);
int x2 = rng.uniform(0, width);
int y2 = rng.uniform(0, height);
int R = rng.uniform(0, 256);
int G = rng.uniform(0, 256);
int B = rng.uniform(0, 256);
//LINE_AA:反锯齿绘制;LINE_4:4邻域绘制;LINE_8:8领域绘制;shift:相对位移
//line(image, Point(x1, y1), Point(x2, y2), Scalar(B, G, R), 2, LINE_AA, 0);
Rect rect;
rect.x = x1;
rect.y = y1;
rect.height = y2 - y1;
rect.width = x2 - x1;
rectangle(image, rect, Scalar(B, G, R), 1, LINE_8, 0); //thickness(线宽)=-1:对图像进行填充;
char ch = waitKey(20);
imshow("image", image);
if (ch == 27)
{
break;
}
}
首先是定义了一个随机数对象(RNG),不是电子竞技啊亲!!!
用这个RNG对象来随机生成绘制几何形状的坐标和颜色。
然后定义一张全黑的画布,作为绘制的区域。
再使用rng.uniform(a, b)
分别生成随机坐标和RGB值,注意该函数生成[a, b)之间的随机数,包含a,但是不包含b。
如果绘制线段的话,就使用line(image, Point(x1, y1), Point(x2, y2), Scalar(B, G, R), 2, LINE_AA, 0)
,其中第一个参数就是画布;第二个参数是线段起点;第三个参数是线段的终点;第四个参数是线段的颜色,用函数Scalar()
来赋值;第五个参数是线段的宽度;第六个参数是绘制方式,有以下几种方式 { LINE_AA:反锯齿绘制;LINE_4:4邻域绘制;LINE_8:8领域绘制 } ;第七个参数
shift表示相对位移,一般取0。
如果绘制矩形,就得先定义一个Rect类对象并初始化,再用rectangle(image, rect, Scalar(B, G, R), 1, LINE_8, 0)
来绘制,其参数和绘制线段的函数是大同小异的。如果要对矩形进行填充,只需要将参数thickness(线宽) = -1 就可以了。
由于我这里使用了for循环绘制很多很多的矩形或线段,所以看起来有些眼花缭乱,效果如下图:
2. ROI(region of interest)感兴趣区域提取
int width = image.cols;
int height = image.rows;
int x = width / 2 - 50;
int y = height / 2 - 50;
Rect rect(x, y, x+50, y+50);
mat roi;
roi = image(rect); //将区域提取出来,但该区域仍然指向原图
roi = image(rect).clone(); //复制成新图像, 不指向原图
roi.setto(scalar(0, 0, 0));
imshow("roi", roi);
ROI区域也就是我们所感兴趣的区域,有时候我们只是想对某个区域进行处理而不对整幅图像,这时候就需要通过ROI提取来得到我们要的处理区域。在前面我们绘制几何形状的基础上,我们就可以将绘制了的矩形区域从图像中提取出来。
当我们已经拥有了一个矩形rect时,可以通过roi = image(rect)
或者roi = image(rect).clone()
来将图像中的该区域提取到Mat对象roi中。要注意的是,如果使用第一个方式提取区域,那么roi表示的区域仍然是指向原图的,如果对roi进行修改,原图也会被修改;如果用第二种方式提取区域,那么roi就是一幅新的与原图无关的图像,例如将roi置为全黑的图像,原图是不会受到影响的。
同样我们可以根据自己的需求来选择使用哪种方法进行ROI区域提取。
代码中roi.setto(scalar(0, 0, 0))
这一行就是将一幅图像置为单一的颜色,具体颜色由Scalar(B、G、R)来确定。
需要注意的是,当我们提取出图像的roi区域后,如果要将这个区域显示为另一张图像(例如将两张图像合并,创建输出图像dst后要把其中一部分显示一张图像,另一部分显示另一张图像),需要使用Mat().copyto()
来将显示图像复制给roi区域。不能使用直接赋值的方式或者Mat().clone()
方法来进行赋值,否则相当于将roi区域重新生成一张图像,不会修改输出图像dst中的内容!!!
本次整理结束,下次再继续~
PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!