• 怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图?


      分类: OpenCV

    【Q1】怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图?

    进行灰度化,IplImage* pImg = cvLoadImage( "C:\1.bmp", 0 ); 这样图像已经灰度化,然后调用cvThreshold(image, image, 125, 255, CV_THRESH_BINARY); 就可以了,125那里是你所用的阈值,这就是最简单的二值化,你要用ostu,或者别的高级一点的,就要自己写函数了

     

    // Truncate values above 100.
      cvThreshold( s, dst, 100, 255, CV_THRESH_TRUNC );//对大于100的像素值进行截断,大于100则为255,不大于100的为原值
      

    【Q2】cvLine画直线

    CvScalar color = CV_RGB(50,0,250);
    cvLine( img1, p1, q1, color, 1, CV_AA, 0 );
    cvLine( img1, p2, q2, color, 1, CV_AA, 0 );
    cvLine( img1, p1, p2, color, 1, CV_AA, 0 );
    cvLine( img1, q1, q2, color, 1, CV_AA, 0 );

    or

    cvLine(image,epipolarLinePoint1,epipolarLinePoint2,CV_RGB(0,255,0));

    cv::Line

    CV_RGB 创建一个色彩值. #define CV_RGB( r, g, b ) [编辑] cvScalar( (b), (g), (r) ) Line 绘制连接两个点的线段 void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 ); img 图像。 pt1 线段的第一个端点。 pt2 线段的第二个端点。 color 线段的颜色。 thickness 线段的粗细程度。 line_type 线段的类型。 8 (or 0) - 8-connected line(8 邻接)连接 线。 4 - 4-connected line(4 邻接)连接线。 CV_AA - antialiased 线条。 shift 坐标点的小数点位数。 函数 cvLine 在图像中的点 1 和点 2 之间画一条线段。线段被图像或感兴趣的 矩形(ROI rectangle)所裁剪。对于具有整数坐标的 non-antialiasing 线条, 使用 8-连接或者 4-连接 Bresenham 算法。画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏 CV_RGB( r, g, b )。

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    cvLoadImage函数使用方法 

    四、图像处理
     
    1、图像的内存分配与释放

    (1) 分配内存给一幅新图像:

    IplImage* cvCreateImage(CvSize size, int depth, int channels);

        size: cvSize(width,height);

        depth: 像素深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,

       IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F

        channels: 像素通道数. Can be 1, 2, 3 or 4.

            各通道是交错排列的. 一幅彩色图像的数据排列格式如下:

                b0 g0 r0 b1 g1 r1 ...

    示例:

    // Allocate a 1-channel byte image
    IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
     
    // Allocate a 3-channel float image
    IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);

     
    (2) 释放图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
    cvReleaseImage(&img);

     
    (3) 复制图像:

    IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
    IplImage* img2;
    img2=cvCloneImage(img1);  // 注意通过cvCloneImage得到的图像
                          // 也要用 cvReleaseImage 释放,否则容易产生内存泄漏

     
    (4) 设置/获取感兴趣区域ROI:

    void  cvSetImageROI(IplImage* image, CvRect rect);
    void  cvResetImageROI(IplImage* image);
    CvRect cvGetImageROI(const IplImage* image);

    大多数OpenCV函数都支持 ROI.
     
    (5) 设置/获取感兴趣通道COI:

    void cvSetImageCOI(IplImage* image, int coi); // 0=all
    int cvGetImageCOI(const IplImage* image);

    大多数OpenCV函数不支持 COI.
     
    2、图像读写
     
    (1) 从文件中读入图像:

    IplImage* img=0; 
      img=cvLoadImage(fileName);
      if(!img) printf("Could not load image file: %s ",fileName);

     支持的图像格式: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM,
                              SR, RAS, TIFF, TIF

    OpenCV默认将读入的图像强制转换为一幅三通道彩色图像. 不过可以按以下方法修改读入方式:

    img=cvLoadImage(fileName,flag);

     flag: >0 将读入的图像强制转换为一幅三通道彩色图像
           =0 将读入的图像强制转换为一幅单通道灰度图像
           <0 读入的图像通道数与所读入的文件相同.

     
    (2) 保存图像:

    if(!cvSaveImage(outFileName,img)) printf("Could not save: %s ", outFileName);

    保存的图像格式由 outFileName 中的扩展名确定.
     
    3、访问图像像素
     
    (1) 假设你要访问第k通道、第i行、第j列的像素。
     
    (2) 间接访问: (通用,但效率低,可访问任意格式的图像)

        * 对于单通道字节型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    CvScalar s;
    s=cvGet2D(img,i,j); // get the (i,j) pixel value
    printf("intensity=%f ",s.val[0]);
    s.val[0]=111;
    cvSet2D(img,i,j,s); // set the (i,j) pixel value

        * 对于多通道字节型/浮点型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
    CvScalar s;
    s=cvGet2D(img,i,j); // get the (i,j) pixel value
    printf("B=%f, G=%f, R=%f ",s.val[0],s.val[1],s.val[2]);
    s.val[0]=111;
    s.val[1]=111;
    s.val[2]=111;
    cvSet2D(img,i,j,s); // set the (i,j) pixel value

     
    (3) 直接访问: (效率高,但容易出错)

        * 对于单通道字节型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    ((uchar *)(img->imageData + i*img->widthStep))[j]=111;

        * 对于多通道字节型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
    ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
    ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
    ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R

        * 对于多通道浮点型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
    ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
    ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
    ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R

     
    (4) 基于指针的直接访问: (简单高效)

        * 对于单通道字节型图像:

    IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    int height     = img->height;
    int width      = img->width;
    int step       = img->widthStep/sizeof(uchar);
    uchar* data    = (uchar *)img->imageData;
    data[i*step+j] = 111;

        * 对于多通道字节型图像:

    IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
    int height     = img->height;
    int width      = img->width;
    int step       = img->widthStep/sizeof(uchar);
    int channels   = img->nChannels;
    uchar* data    = (uchar *)img->imageData;
    data[i*step+j*channels+k] = 111;

        * 对于多通道浮点型图像(假设图像数据采用4字节(32位)行对齐方式):

    IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
    int height     = img->height;
    int width      = img->width;
    int step       = img->widthStep/sizeof(float);
    int channels   = img->nChannels;
    float * data    = (float *)img->imageData;
    data[i*step+j*channels+k] = 111;

     
    (5) 基于 c++ wrapper 的直接访问: (更简单高效)

        * 首先定义一个 c++ wrapper ‘Image’,然后基于Image定义不同类型的图像:

    template<class T> class Image
    {
      private:
      IplImage* imgp;
      public:
      Image(IplImage* img=0) {imgp=img;}
      ~Image(){imgp=0;}
      void operator=(IplImage* img) {imgp=img;}
      inline T* operator[](const int rowIndx) {
        return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
    }; 
     
    typedef struct{
      unsigned char b,g,r;
    } RgbPixel; 
     
    typedef struct{
      float b,g,r;
    } RgbPixelFloat; 
     
    typedef Image<RgbPixel>       RgbImage;
    typedef Image<RgbPixelFloat>  RgbImageFloat;
    typedef Image<unsigned char>  BwImage;
    typedef Image<float>          BwImageFloat;

        * 对于单通道字节型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    BwImage imgA(img);
    imgA[i][j] = 111;

        * 对于多通道字节型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
    RgbImage  imgA(img);
    imgA[i][j].b = 111;
    imgA[i][j].g = 111;
    imgA[i][j].r = 111;

        * 对于多通道浮点型图像:

    IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
    RgbImageFloat imgA(img);
    imgA[i][j].b = 111;
    imgA[i][j].g = 111;
    imgA[i][j].r = 111;

     
    4、图像转换
     
    (1) 字节型图像的灰度-彩色转换:

    cvConvertImage(src, dst, flags=0);

     src = float/byte grayscale/color image
     dst = byte grayscale/color image
     flags = CV_CVTIMG_FLIP     (垂直翻转图像)
             CV_CVTIMG_SWAP_RB  (置换 R 和 B 通道)

     
    (2) 彩色图像->灰度图像:

    // Using the OpenCV conversion: 
    cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg 
     
    // Using a direct conversion: 
    for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++) 
      gimgA[i][j]= (uchar)(cimgA[i][j].b*0.114 + 
                           cimgA[i][j].g*0.587 + 
                           cimgA[i][j].r*0.299);

     
    (3) 不同彩色空间之间的转换:

    cvCvtColor(src,dst,code); // src -> dst

     code    = CV_<X>2<Y>
     <X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS

    e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab
     
    5、绘图指令
     
    (1) 绘制矩形:

    // 在点 (100,100) 和 (200,200) 之间绘制一矩形,边线用红色、宽度为 1
    cvRectangle(img, cvPoint(100,100), cvPoint(200,200), cvScalar(255,0,0), 1);

     
    (2) 绘制圆形:

    // 圆心为(100,100)、半径为20. 圆周绿色、宽度为1
    cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);

     
    (3) 绘制线段:

    // 在 (100,100) 和 (200,200) 之间、线宽为 1 的绿色线段
    cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,255,0), 1);

     
    (4) 绘制一组线段:

    CvPoint  curve1[]={10,10,  10,100,  100,100,  100,10};
    CvPoint  curve2[]={30,30,  30,130,  130,130,  130,30,  150,10};
    CvPoint* curveArr[2]={curve1, curve2};
    int      nCurvePts[2]={4,5};
    int      nCurves=2;
    int      isCurveClosed=1;
    int      lineWidth=1; 
     
    cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);
     
    void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,
                              CvScalar color, int thickness=1, int line_type=8, int shift=0 );
    img       图像。 
    pts       折线的顶点指针数组。 
    npts     折线的定点个数数组。也可以认为是pts指针数组的大小 
    contours   折线的线段数量。 
    is_closed  指出多边形是否封闭。如果封闭,函数将起始点和结束点连线。 
    color         折线的颜色。 
    thickness  线条的粗细程度。 
    line_type  线段的类型。参见cvLine。 
    shift          顶点的小数点位数

     
    (5) 绘制一组填充颜色的多边形:

    cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));
     
    cvFillPoly用于一个单独被多边形轮廓所限定的区域内进行填充。函数可以填充复杂的区域,例如,有漏洞的区域和有交叉点的区域等等。
    void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,CvScalar color, int line_type=8, int shift=0 );
    img           图像。 
    pts           指向多边形的数组指针。 
    npts         多边形的顶点个数的数组。 
    contours   组成填充区域的线段的数量。 
    color         多边形的颜色。 
    line_type  组成多边形的线条的类型。 
    shift          顶点坐标的小数点位数。

     
    (6) 文本标注:

    CvFont font;
    double hScale=1.0;
    double vScale=1.0;
    int    lineWidth=1;
    cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
     
    cvPutText (img,"My comment",cvPoint(200,400), &font, cvScalar(255,255,0));

    其它可用的字体类型有: CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN, CV_FONT_HERSHEY_DUPLEX, CV_FONT_HERSHEY_COMPLEX, CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL, CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX,

    /////////////////////////////////////////////////  参考  /////////////////

         cvLoadImage( filename, -1 ); 默认读取图像的原通道数

     

      cvLoadImage( filename, 0 ); 强制转化读取图像为灰度图

     

      cvLoadImage( filename, 1 ); 读取彩色图

     

      例:将读入图像强制转换为灰度图像显示

     

      #include <highgui.h>

     

      #include <cv.h>

     

      int main(int argc, char **argv)

     

      {

     

      if (argc != 2)

     

      return -1;

     

      

     

      IplImage *img = cvLoadImage(argv[1], 0);

     

      cvNamedWindow("example");

     

      cvShowImage("example", img);

     

      cvWaitKey(0);

     

      cvReleaseImage(&img);

     

      cvDestroyWindow("example");

     

      return 0;

     

      }

  • 相关阅读:
    Nginx+Keepalived实现简单的服务高可用
    搭建私有镜像仓库
    GlusterFS
    GlusterFS分布式存储系统
    GlusterFS分布式存储
    ladp日志配置
    go mod位置和自定义包引入问题
    .netcore 使用redis
    一篇技术博文引发的stylelint项目实践
    React Hooks使用避坑指南
  • 原文地址:https://www.cnblogs.com/okgogo2000/p/4809218.html
Copyright © 2020-2023  润新知