题目5:学习使用感兴趣区域(ROI)。创建一个210*210的单通道图像并将其归0。在图中使用ROI和cvSet建立一个增长如金字塔状的数组,也就是:外部边界为0,下一个内部边界应该为20,在下一个内部边界为40,依此类推,直到最后内部值为200,所有边界应该为10个像素宽度。最后显示这个图形。
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main ()
{
//创建一个210*210的单通道图像
IplImage* img = cvCreateImage(cvSize(210,210),8,1);
//归0
cvZero(img);
int EdgeDistance=20;
int EdgeWidth=10;
for(int i = 0; i<= img->width-EdgeDistance; i=i+EdgeDistance+EdgeWidth)
{
CvPoint pt = cvPoint(i,i);
CvRect RectROI1 = cvRect(pt.x,pt.y,img->width-pt.x,EdgeWidth);
cvSetImageROI(img,RectROI1);
cvSet(img,cvScalar(255));
cvResetImageROI(img);
}
for(int i = 0; i<= img->width-EdgeDistance; i=i+EdgeDistance+EdgeWidth)
{
CvPoint pt = cvPoint(i,i);
CvRect RectROI2 = cvRect(pt.x,pt.y,EdgeWidth,img->height-pt.y);
cvSetImageROI(img,RectROI2);
cvSet(img,cvScalar(255));
cvResetImageROI(img);
}
cvNamedWindow("src");
cvShowImage("src",img);
cvWaitKey(0);
cvDestroyWindow("src");
cvReleaseImage(&img);
return 0;
}
效果图:
题目7:使用cvCmp()创建一个掩码。加载一个真实的图像。使用cvSplit()将图像分割成红,绿,蓝三个单通道图像。
a. 找到并显示绿图。
b. 克隆这个绿图两次(分别命名为clone1和clone2)。
c. 求出这个绿色平面的最大值和最小值。
d. 将clone1的所有元素赋值为thresh=(unsigned char)((最大值-最小值)/2.0)。
e. 将clone2所有元素赋值为0,然后调用函数cvCmp (green_image, clone1, clone2, CV_CMP_GE)。现在clone2将是一个标识绿图中值超过thresh的掩码图像。
f. 最后,使用cvSubS(green_image,thresh/2, green_image, clone2)函数并显示结果。
/*
使用cvCmp()创建一个掩码。加载一个真实的图像。使用cvSplit()将图像分割成红,绿,蓝三个单通道图像。
a. 找到并显示绿图。
b. 克隆这个绿图两次(分别命名为clone1和clone2)。
c. 求出这个绿色平面的最大值和最小值。
d. 将clone1的所有元素赋值为thresh=(unsigned char)((最大值-最小值)/2.0)。
e. 将clone2所有元素赋值为0,然后调用函数cvCmp (green_image, clone1, clone2, CV_CMP_GE)。现在clone2将是一个标识绿图中值超过thresh的掩码图像。
f. 最后,使用cvSubS(green_image,thresh/2, green_image, clone2)函数并显示结果。
*/
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void main ()
{
IplImage *img = cvLoadImage("pic.jpg");
IplImage *RedImage=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
IplImage *GreenImage=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
IplImage *BlueImage=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
IplImage *clone1,*clone2;
cvSplit(img,BlueImage,GreenImage,RedImage,0);
cvShowImage("blue",BlueImage);
cvShowImage("red",RedImage);
//a. 找到并显示绿图。
cvShowImage("Green",GreenImage);
//b.克隆这个绿图两次
clone1=cvCloneImage(GreenImage);
clone2=cvCloneImage(GreenImage);
//c. 求出这个绿色平面的最大值和最小值。
double Max = 255;
double Min = 50;
cvMinMaxLoc(clone1,&Min,&Max);
//d.将clone1的所有元素赋值为thresh=(unsigned char)((最大值-最小值)/2.0)
double thresh=(Max-Min)/2.0;
cvSet(clone1,cvScalar(thresh));
//e. 将clone2所有元素赋值为0,然后调用函数cvCmp (green_image, clone1, clone2, CV_CMP_GE)。现在clone2将是一个标识绿图中值超过thresh的掩码图像。
cvSet(clone2,cvScalar(0));
cvCmp(GreenImage,clone1,clone2,CV_CMP_GE);
//f. 最后,使用cvSubS(green_image,thresh/2, green_image, clone2)函数并显示结果。
cvSubS(GreenImage,cvScalar(thresh/2),GreenImage,clone2);
//显示
cvShowImage("clone1",clone1);
cvShowImage("clone2",clone2);
cvWaitKey(0);
cv::destroyAllWindows();
}
效果图:
题目8:创建一个结构,结构中包含一个整数,一个CvPoint和一个CvRect;称结构为"my_struct"。
a. 写两个函数:void write_my_struct(CvFileStorage* fs, const char * name, my_struct* ms)
和 void read_my_struct(CvFileStorage* fs, CvFileNode* ms_node, my_struct* ms)
b. 创建一个元素为my_struct结构体且长度为10的数组,并将数组写入磁盘和从磁盘读入内存。
/*
创建一个结构,结构中包含一个整数,一个CvPoint和一个CvRect;称结构为"my_struct"。
a. 写两个函数:void write_my_struct(CvFileStorage* fs, const char * name, my_struct* ms)
和 void read_my_struct(CvFileStorage* fs, CvFileNode* ms_node, my_struct* ms)
b. 创建一个元素为my_struct结构体且长度为10的数组,并将数组写入磁盘和从磁盘读入内存。
*/
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
typedef struct my_struct{
int data;
CvPoint pt;
CvRect rect;
}my_struct;
void write_my_struct(CvFileStorage* fs, const char * name, my_struct* ms)
{
cvWriteInt(fs,name,10);
//开始写入新的数据结构
cvStartWriteStruct(fs,"int",CV_NODE_SEQ);
cvWriteInt(fs,0,ms->data);
//结束写入数据结构
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"CvPoint",CV_NODE_SEQ);
cvWriteInt(fs,0,ms->pt.x);
cvWriteInt(fs,0,ms->pt.y);
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"CvRect",CV_NODE_SEQ);
cvWriteInt(fs,0,ms->rect.x);
cvWriteInt(fs,0,ms->rect.y);
cvWriteInt(fs,0,ms->rect.height);
cvWriteInt(fs,0,ms->rect.width);
cvEndWriteStruct(fs);
}
void read_my_struct(CvFileStorage* fs, CvFileNode* ms_node, my_struct* ms)
{
//读取文件
fs=cvOpenFileStorage("data.xml",0,CV_STORAGE_READ);
//查找文件节点返回它的值
int value = cvReadIntByName(fs,0,"int",1);
//在图表或者文件存储器中查找节点
CvSeq* s = cvGetFileNodeByName(fs,0,"CvPoint")->data.seq;
CvSeq* r = cvGetFileNodeByName(fs,0,"CvRect")->data.seq;
//从文件节点中得到整形值,cvGetSeqElem用来检测序列
int point_x = cvReadInt((CvFileNode*)cvGetSeqElem(s,0));
int point_y = cvReadInt((CvFileNode*)cvGetSeqElem(s,1));
int rect_x = cvReadInt((CvFileNode*)cvGetSeqElem(r,0));
int rect_y = cvReadInt((CvFileNode*)cvGetSeqElem(r,1));
int rect_height = cvReadInt((CvFileNode*)cvGetSeqElem(r,2));
int rect_width = cvReadInt((CvFileNode*)cvGetSeqElem(r,3));
cout<<"点:("<<point_x<<","<<point_y<<")"<<endl;
cout<<"矩阵数据:"<<endl;
cout<<"起始点坐标为:("<<rect_x<<","<<rect_y<<")"<<endl;
cout<<"矩阵宽度:"<<rect_width<<endl;
cout<<"矩阵高度:"<<rect_height<<endl;
cvReleaseFileStorage(&fs);
}
int main()
{
//创建data.xml
CvFileStorage* fs=cvOpenFileStorage("data.xml",0,CV_STORAGE_WRITE);
//创建内容
my_struct myst={10,cvPoint(5,5),cvRect(0,0,1,5)};
//写
write_my_struct(fs,"data",&myst);
cvReleaseFileStorage(&fs);
//读
read_my_struct(fs,NULL,&myst);
system("pause");
return 0;
}
效果图: