opencv 一年多的初级总结

至2016.9.2

1
P127
addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,  
              logoImage,0.5,0.,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)));


2
000  书P166
boxFilter( grayimage,grayimage,-1,Size(5,5));  方框滤波


3
进度条
createTrackbar("进度条","效果图",&g_nThresholdValue,255,trackbarr);   &不能忘记


4
高斯滤波中有的
遇到Size ksize的参数形式,实际编程就是Size(3,3)的形式(有时要求只能是正奇数的形式)


5
Mat::Mat(int rows, int cols, int type, const Scalar& s),,于仕琪24页,Mat::Mat()无参数构造方法;
创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始化为值s;


6,,28
uchar value = grayim.at<uchar>(i,j);//读出第 i 行第 j 列像素值,这是一个数
还有一种是: grayim.at<Vec3b>(i,j)[0],[1],[2];书P113,这样就不用考虑列数要乘3了吧


7
Mat colorim(600, 800, CV_8UC3);//这是创建两个画布吧?? 程序于仕琪P28
Mat image = Mat::zeros( 600, 800, CV_8UC3 );这个语句是全黑屏//Mat image(640, 1024, CV_8UC3);这个语句全白屏


8...33
roi 是表示 img 中 Rect(10,10,100,100)区域的对象
Mat roi(img, Rect(10,10,100,100));
Mat roi=img(Rect(10,10,100,100));
Mat B=img(Range::all(),Range(1,300));这样也行,感觉opencv很激活
img4=img((Rect(100,100,233,322))|(Rect(180,180,300,200)));
//Point point=Point(105,85);Mat shift=img(Rect(0,0,300,400)+point),,见程序315,point用来控制起点


9******************
于仕琪  P32 改变一行或一列,有for循环,,横纵都有的***这个程序中有个不懂得


10  ********  vector函数
vector<T>  v1;     vector保存类型为T的对象。默认构造函数v1为空。
vector<T> v2(v1); v2是v1的一个副本。
vector<T> v3(n, i); v3包含n个值为i的元素。
vector<T> v4(n); v4含有值初始化的元素的n个副本。


vector<KeyPoint> keypoints1
就是放KeyPoint对象的一个vector   (keypoints1是放KeyPoint对象的一个vector??????????)


vector<int>,就是存放int变量,类似于int a[10]或者int* a,但是vector里边存放
变量的个数不限。显然vector<int>不是二维的。
类似vector<point>和vector<int>一样,只不过存放的是point类型的变量。你之所
以觉得他是二维的,可能是因为存放的point是二维点。
你也可以声明mat型的向量,vector<mat>,这个里边的数据类型当然维数就不定了。




11*******见程序P111.。。指针法
uchar* data=outputImage.ptr<uchar>(i);老遇到这样的额,什么意思?
Mat最直接的访问方法是通过.ptr<>函数得到一行的指针,并用[]操作符访问某一列的像素值。
 比如uchar* data= image.ptr<uchar>(j);
for (int i=0; i<nc; i++) {  
       data[i]= data[i]/div*div + div/2;   
也可用指针法: *data++= *data/div*div + div/2;      见网址http://blog.csdn.net/xiaowei_cqu/article/details/19839019




12
定义随机   RNG rng(949);
rng.uniform(a,b) 。这指定了一个在 a 和 b 之间的均匀分布(包含 a, 但不含 b)。


13   见程序“opencv官网随机数字发生器"
Point org;//
    org.x = rng.uniform( x_1, x_2);
    org.y = rng.uniform(y_1, y_2 );


14*********这个Mat语句啥意思?程序见000数豆豆。。。
    Mat dstImage=Mat::zeros(image.rows,image.cols,CV_8UC3);
image=(image<20); //这个语句相当于二值化了
imshow("取阈值后的原始图",image);


15
//Mat dst=image<100;//用于反色,,不是吧
   //imshow("fan",dst);


16********这种关于rect的定义也是。。。
CvRect rect;  
    rect.x=130,rect.y=30,rect.width=200,rect.height=200;  
    res=cvLoadImage("C:/Users/lufee/Pictures/cat.jpg");//载入一张图片  
    dst=cvCreateImage(cvSize(200,200),8,3);//创建图像空间  
  
    //创建窗口  
    cvNamedWindow("res",CV_WINDOW_AUTOSIZE);  
    cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);  
  
    //设置ROI区域  
    cvSetImageROI(res,rect); 


17,,释放感兴趣区域,见例程wx7
释放基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
格式:  void cvResetImageROI(IplImage* image)


18,见例程 字符水平垂直分割
 int *colheight =new int[srcImage.cols]; 
    memset(colheight,0,srcImage.cols*4);  //数组必须赋初值为零,否则出错。无法遍历数组


19,掩膜,见程序250canny
  src1.copyTo( dst, edge);  使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中  


20,//大津法,自动阈值threshold( g_grayImage, g_dstImage, 0, 255,CV_THRESH_OTSU);,,见P240基本阈值操作,自己写的,不带滑动条




21,三通道颜色的赋值,见程序“000计算空白图像的面积”,,Size2f是2通道的,uchar就是单通道的。
             srcimage.at<Vec3b>(i,j)[0]=0;  
             srcimage.at<Vec3b>(i,j)[1]=255;  
             srcimage.at<Vec3b>(i,j)[2]=255;
区别于单通道颜色赋值gray.at<uchar>(i,j)=99;




22,r=sqrt(double((x1-a)^2+(x2-b)^2));开根号必须要这么用啊?必须要有double,见程序分区计算面积,,错了,^根本就不是语言运算符,只不过是习语




23,double x1=4,y1=4;
double a=pow(x1,y1);&&&&&&&&&&&&&&&&&指数还必须要这么写??4的4次方,int的定义不行




24//float a=300,b=300,x1=200,y1=50,x2=400,y2=150;
这里的x1,y1等形式不能当变量用,貌似他们是指针特有的形式*************
程序见“000简单地画一段圆弧”


25, argv[1] = "D:/2.jpg";这个可能是按路径读图片,图片名还是2,下次试试




26,char* source_window = "Source";这是创建窗口还是宏定义?程序P314...有




27.vector<T>vec[10]定义了一个长度为10的数组,数组元素的类型向量,向量的数据类型是T
   vector<T>vec(10)定义了一个长度为10的向量,向量的数据类型是T




28.contours的定义和调用格式,见程序,凸包。。。
   vector<vector<Point> > contours;
   convexHull( contours[i], hull[i], false ); }


29.书P341,hull.size()是把hull转化成一个数,但是hull本来是啥啊/、,啥形式的东西




30.书P322 Point2f center;是定义一个二维点center。


31.程序P320左右。。,我估计要求二维点集的数据类型都可以用查找边界的contour数据。。书P319最上
       approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );//逼近多边形曲线
       boundRect[i] = boundingRect( Mat(contours_poly[i]) );//寻找外部矩形边界
       minEnclosingCircle( contours_poly[i], center[i], radius[i] );//寻找最小包围圆形


32,见周斌的程序wx7,,感兴趣区域直接这样指定也行是吧?
 CvRect rc =cvBoundingRect(c,0);
cvSetImageROI(imgSrc, rc);




33,见程序P320左右,,这里的tl()和br是固定的?
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); //topleft。。bottomright。。左上,右下




34.我该如何写一个语句就能显示这么多?见程序hengxiangtouying
 imshow("第1个字符小块",img1);
imshow("第2个字符小块",img2);
imshow("第3个字符小块",img3);
imshow("第4个字符小块",img4);
imshow("第5个字符小块",img5);
imshow("第6个字符小块",img6);
imshow("第7个字符小块",img7);
imshow("第8个字符小块",img8);


35,见程序P77,啥意思,为啥这么写,把数值改了也没影响啊????????????
g_rectangle=Rect(0,0,-1,-1);


36。见程序P77,,为什么定义一个函数要在括号里加这些东西???
  void DrawRectangle(cv::Mat& img,cv::Rect box)




37,c.push_back(X) 将元素X加入到c容器的最后一位。


c.back() 返回c容器的最后一个元素的值,并不是该元素的地址。
例子,,输出为1换行2,见http://zhidao.baidu.com/link?url=K_5mX9mRMx_VdFKCxChzuRbxq
36nrC4yQuEmN2juNNL9oTginiQIlt5WfPnecTxMbkrHXfVJE-6sXONza6a-3q
#include <iostream>  #include <vector>
using namespace std;
int main(){  vector<int> vi;
    vi.push_back(1);    cout << vi.back() << endl;
    vi.push_back(2);     cout << vi.back() << endl;
    return 0;}


38,见程序P_111访问,,,,指针法
访问像素uchar* data=outputImage.ptr<uchar>(i);这样获取行的首地址
比outputImage.at<uchar>(i,j)单个像素操作要快,




39,书P131写的,我这样不是相当于增加了对比度吗,,为什么结果出现黑块?
img2=img.clone();
for(int i=0;i<img.rows;i++)
   {    for(int j=0;j < img.cols;j++) 
{    
img2.at<uchar>(i,j)= (img.at<uchar>(i,j))*2;
if(img2.at<uchar>(i,j)>255) img2.at<uchar>(i,j)=255;}}




40,见程序P132图像亮度,,,saturate_cast<uchar>是溢出保护,大致原理是
  if(data<0) data=0;    else if(data>255) data=255;  


41,见程序P356,创建HSV格式的图片,创建的图片类型同hsv_base的图片类型。
 hsv_half_down = hsv_base( Range( hsv_base.rows/2, 
hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );//这是直接创建矩形???
  imshow("半身图",hsv_half_down);


42,MatIn=~MatIn;//,这一句的作用是反向,见程序opencv2016,03,04去除面积小于一定值的点,拐叔




43,float c;int a,b;  c=b/a;这样是没有结果的只要A和B中有一个是float就可以的了,另:float比int容纳的数据小吗?


44,反正切是atan2(a,b),正切是tan(c),abc皆为浮点型,sin 和 cos都可以用,,但是cot不能用
    绝对值是这样的  int ji=-9;    int jia=abs( ji);


45, int cvRound (double value) 对一个double型的数进行四舍五入,并返回一个整型数


46,int main()//////多维转一维??也没弄懂别人问的啥意思。。。
{
  Mat src=(Mat_<double>(3,3)<<1,2,2,
                                  3,5,4,
                                                          6,8,4); 
  Mat line =src.reshape(0,1);
  cout<<src<<endl;
   cout<<line<<endl;
   system("pause");
}


47,cout<<contours[i]<<endl;见程序P306
    这个输出轮廓坐标的语句,原理是当连续的几个点横坐标相同纵坐标依次增加时 只输出首尾两个点,所以输出坐标看起来不连续
    CHAIN_APPROX_NONE是不压缩的,CHAIN_APPROX_SIMPLE是压缩的




48,drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
   这里的 i 换成 1 就表示不画出最外层矩形轮廓


49,cvPointPolygonTest 函数决定测试点是否在轮廓内,轮廓外,还是轮廓的边上(或者共边的交点上),
它的返回值是正负零,相对应的,当measure_dist=0时,返回值是1, -1,0, 同样当 measure_dist≠0 ,
它是返回一个从点到最近的边的带符号距离。


50, minMaxLoc(hist, &min_val, &max_val, 0, 0);绘制一串数据的最大最小值,见程序opencv绘制灰度直方图


51,IplImage* src = cvLoadImage( argv[1] );的读取图片方式
    参数【2.jpg】需要这样设置:右键解决方案资源管理器中的项目名字,
    选择【属性】,依次是【配置属性】->【调试】->【命令参数】


52,flip(img,img,-1);//图像翻转,第三个数0,1,和负数表示按不同的轴翻转


53,contourArea估计轮廓区域的面积(里面的像素数)。函数cv::pointPolygonTest计算一个点是否在轮廓内


54,程序见306.。。这是对轮廓大小进行筛选的语句contours.erase
int cmin = 100;  
int cmax = 1000;  
std::vector<std::vector<Point>>::const_iterator itc = contours.begin();  
while(itc != contours.end())  
{  
    if(itc->size() < cmin || itc->size() > cmax)  
        itc = contours.erase(itc);  
    else  
        ++itc;  
}  


55,CV_RGB( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) )这个颜色随机性更好也要RNG rng(12345);


56,resize( temp,img,  img.size(),0, 0, 0 );调整图一跟图二一样大


57,执行image1=dstImage.clone();以后对dstImage的操作不会影响到image1,,而image1=dstImage,对后者操作会影响前者


58,pointPolygonTest函数可以输出一个点到最近边缘的距离,见程序20160330


59.********for 循环中该清零的变量一定不要忘记清零 ! ! ! ! ! ! ! ! 1 1 1 ! 


60,细节,,见程序00020160328,轮廓个参数
  if(nn>3&&( abs(contours[1][i].y-contours[1][0].y)<2)&&( abs(contours[1][i].x-contours[1][0].x)<2))break;
 //记得这里一定要加绝对值,不然遇到两个峰值一样的图片会出错,如图6,,,还有这里最好写小于2防止出错!!!


61,扩充边界,四个参数分别为上下左右
 copyMakeBorder(inputImg, tempImg, 10, 20, 30, 40, BORDER_CONSTANT);


62,cvRound 表四舍五入。。


63,opencv 20160426,m00就相当于轮廓的面积, 
   { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }//计算重心坐标


64,Mat B = image.t();表示图片image的转置,,其实一副图就是一个矩阵
 
65, Mat sharpened = image*2 + blurred*(-1);对图像锐化,blurred表高斯模糊后的图;


66,各种矩阵运算,也不太明白啥意思,,opencv2refman  P32 左右
image.convertTo(image2, 1, 1.2,1) ;
66.1 Mat C = image1.mul(image1);
66.2 Mat A = Mat::ones(400, 400, CV_8UC1)+255;创建一个白板可以这样!zeros 也行
66.3 Mat A = Mat::eye(400, 400, CV_8UC1)*225; 造一个矩阵,对角线填充白色,
66.4 image2=image.diag(1);//提取图片对角线。 1 是副对角线,见opencv2refman P29
66.5 image3=image(Rect(75,75,50,50));
image3.adjustROI(20, 20, 20, 20);这两句是使ROI区域上下左右浮动20像素,触及image的边缘自动调整
66.6 image.convertTo(image3,CV_32F); 把图像转为CV_32F位深度的,,CV_32F显示的范围是 0 到 1 ,而非0到255


67,偶尔看到网友这样去读取文件的,试了下和 imread 是一个效果
  filename= "D:\\Workspace\\Study\\Learning\\Learn4\\Learn4\\pic.jpeg";
       
  Mat imgsrc = imread(filename);


68,这一直就是一个值得关注的问题,
  Mat_<uchar>对应的是CV_8U,Mat_<uchar>对应的是CV_8U,Mat_<char>对应的是CV_8S,
  Mat_<int>对应的是CV_32S,Mat_<float>对应的是CV_32F,Mat_<double>对应的是CV_64F,
  对应的数据深度如下:http://www.360doc.com/content/13/0415/16/10724725_278434409.shtml
  也可以把原来的IplImage格式的图片直接用Mat(IplImage)的方式转成Mat结构


69,vector<vector<int>>test = vector<vector<int>>(10000, vector<int>(10, 0)); 运行需要100ms
    替换为Mat test1 = Mat_<int>::zeros(10000, 10);  运行只需要0.2ms
      详见  http://blog.csdn.net/yang_xian521/article/details/7107072


70,积分图像integral(temp, temp,  -1 );


71,程序见opencv2016,05,11自动识别手掌位置,用到distanceTransform 和 pointPolygonTest函数
   网上胡乱看的:dst为单通道的32-bit 浮点型矩阵,读取元素时需要用image.ptr<float>(i)[j]


72,函数返回一个坐标值,加一个数值(pair<Point,double>用于返回多个值多个返回值),见 opencv2016,05,11自动识别手掌位置 


73,调整图像大小为原来的一半: resize(image,image,Size(image.cols/2,image.rows/2),0,0,INTER_LINEAR );


74,_Tp的意思就是补上缺失的类型,程序见20160517 1944 LBP官方版,比如引用时写olbp_<uchar>(image, dst);
    template <typename _Tp> static
void olbp_(InputArray _src, OutputArray _dst)


75,bitset<n> b;b有n位,  如bitset<5> b0;则"b0"为"00000";,,就是十进制转二进制数,程序见 20160518 1138  


76,输出二进制数 b 中数字 1 的个数: b.count(), 详见 http://blog.163.com/lixiangqiu_9202/blog/static/53575037201251121331412/


77,IplImage* img->widthStep 表示存储一行像素所需的字节数,widthStep必须是4的倍数。


78,int para[a][b] = {0}; 这样全部赋值0时,a ,b只能是宏定义的变量吗?待验证,如果ab都大于500数组过大貌似也不行,待验证


79,这个是建库依次载入多张图片
    char* names[] = { "001.jpg", "002.jpg", "003.jpg", 0 };
 for( i = 0; names[i] != 0; i++ )
 {
  img0 = cvLoadImage( names[i], 1 );
  if( !img0 )
  {
   cout<<"不能载入"<<names[i]<<"继续下一张图片"<<endl;
   continue;
  }
  img = cvCloneImage( img0 );


80,  Rect aRect = boundingRect(contours[1]);
cout  << "11#contour area:" << aRect << endl;   这样的轮廓输出结果还带坐标,感觉很新奇


81,memset用法http://blog.sina.com.cn/s/blog_500bd63c0101fdm9.html
     char buffer[] = "Hello world\n";
     printf("Buffer before memset: %s\n", buffer);
     memset(buffer, 'H', strlen(buffer) );相当于开辟内存
     printf("Buffer after memset: %s\n", buffer);


82,关于 ptr 详解见书P112


83,float a = 1.f / 2=0.5  float ab = 1 / 2=0   这就是1.f和 1 的区别

猜你喜欢

转载自blog.csdn.net/guanyonglai/article/details/52411225