Opencv第三章

2. 下面这个练习是帮助掌握矩阵类型。创造一个三通道二维矩阵,字节类型,大小为100×100,并设置所有数值为0。

a. 在矩阵中使用void cvCircle(CvArr* img, CvPoint center, intradius, CvScalar color, int thickness=1, int line_type=8, int shift=0)画一个圆。

b. 使用第2章所学的方法来显示这幅图像。

#include <cv.h>
#include <highgui.h>
int main()
{
    CvMat *mat = cvCreateMat(100, 100, CV_32FC3);
    cvZero(mat);

    CvSize rect = cvSize(800, 800);
    IplImage* image = cvCreateImage(rect, IPL_DEPTH_8U, 3);

    CvPoint center = cvPoint(400, 400);
    int radius = 400;
    CvScalar color = cvScalar(100, 100, 100);
    cvCircle(image,center, radius, color, 1, 8, 0);
    
    cvNamedWindow("main", 1);
    //cvNamedWindow("main1", 1);
    cvShowImage("mian", image);
    //cvShowImage("main1", mat);
    cvWaitKey(0);
    cvReleaseImage(&image);
    cvReleaseMat(&mat);
    return 0;

}

3. 创建一个拥有三个通道的二维字节类型矩阵,大小为100x100,并将所有值赋为0。通过函数cvPtr2D 将指针指向中间的通道(“绿色”)。以(20,5)与(40,20)为顶点间画一个绿色的长方形。

#include <cv.h>
#include <highgui.h>
int main()
{
    CvSize size = cvSize(100, 100);
    IplImage *image = cvCreateImage(size, IPL_DEPTH_8U, 3); 
    cvZero(image);
    int left = 20;
    int right = 40;
    int top = 5;
    int bottom = 20;
    for (; top < bottom; top++)
    {
        for (; left < right; left++)
        {
            *(cvPtr2D(image, top, left)+1) = 255;
            //cvPtr2D 参数分别表示在当前的图中,坐标为(top,left)的位置 + 1 为绿色 ;+2 表示红色 ;+0 表示蓝色;
        }
        left = 20;
    }
    cvNamedWindow("main", 1);
    cvShowImage("main", image);
    cvWaitKey();
    cvReleaseImage(&image);
    cvDestroyWindow("main");
    return 0;
}

 4.创建一个大小为100x100的三通道RGB图像。将它的元素全部置0.使用指针算法以(20,5 )与(40,20)为顶点绘制一个绿色平面。

#include <cv.h>
#include <highgui.h>
int main()
{
    CvSize size = cvSize(100, 100);
    IplImage *img = cvCreateImage(size, IPL_DEPTH_8U, 3);
    cvZero(img);
    int left = 20;
    int right = 40;
    int top = 5;
    int bottom = 20;
    for (int i = 0; i < img->height;i++)
    {
        uchar *ptr = (uchar*)(img->imageData + i*img->widthStep);
        //imageData 图像数据的指针 
        //widthStep 校准后的行字节数
        for (int j = 0; j < img->width; j++)
        {
            ptr[j * 3] = 255;
            ptr[j * 3 + 1] = 255;
            ptr[j * 3 + 2] = 255;
        }
    }
    for (; top < bottom; top++)
    {
        uchar *ptr = (uchar*)(img->imageData + top * img->widthStep);
        for (; left < right; left++)
        {
            ptr[left * 3] = 0;
            ptr[left * 3 + 1] = 255;
            ptr[left * 3 + 2] = 0;
        }
        left = 20;
    }
    cvNamedWindow("main", 1);
    cvShowImage("main", img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("main");
    return 0;
}

4.

创建一个210*210的单通道图像并将其归0.在图像中使用ROI和cvSet()建立一个增长如金字塔状的数组。也就是,外部边界为0,下一个内部边界为20,再下一个内部边界为20,
再下一个内部边界为40,以此类推,直到最后内部值为200,所有的边界应该为10像素的宽度。最后显示这个图形。

#include <cv.h>
#include <highgui.h>
int main()
{
    CvSize size = cvSize(210, 210);
    IplImage *img = cvCreateImage(size, IPL_DEPTH_8U, 1);
    cvZero(img);
    for (int i = 0; i <= 20; i++)
    {
        cvSetImageROI(img, cvRect(100-i*5, 0+i*10, 10+i*10, 10));
        cvAddS(img, cvScalar(255), img);
    }
    /*
    cvSetImageROI(img, cvRect(100, 0, 10, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(95, 10, 20, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(90, 20, 30, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(85, 30, 40, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(80, 40, 50, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(75, 50, 60, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(70, 60, 70, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(65, 70, 80, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(60, 80, 90, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(55, 90, 100, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(50, 100, 110, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(45, 110, 120, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(40, 120, 130, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(35, 130, 140, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(30, 140, 150, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(25, 150, 160, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(20, 160, 170, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(15, 170, 180, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(10, 180, 190, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(5, 190, 200, 10));
    cvAddS(img, cvScalar(255), img);
    cvSetImageROI(img, cvRect(0, 200, 210, 10));
    cvAddS(img, cvScalar(255), img);
    */
    cvResetImageROI(img);
    cvNamedWindow("mian", 1);
    cvShowImage("main", img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("main");
    return 0;
}

 6.为一个图像创建多个图像头。读取一个大小至少为100x100的图像。另外创建两个图像头并设置他们的origion,depth,nChannels和widthStep属性同之前读取的图像一致,

在新的图像头中,设置宽度为20,高度为30。最后将imageData指针分别指向像素(5,10)和(50,60)像素位置,传递这两个新的图像头给cvNot。最后显示最初读取的图像,在那个大的图像中有应该有两个矩阵,矩阵内的值是原始值得求反值。

#include <cv.h>
#include <highgui.h>
int main()
{
    IplImage *img = cvLoadImage("001.jpg",1);
    IplImage *src1 = cvCreateImageHeader(cvSize(20,30), img->depth, img->nChannels);
    IplImage *src2 = cvCreateImageHeader(cvSize(20,30), img->depth, img->nChannels);
    src1->origin = img->origin;
    src2->origin = img->origin;
    src1->widthStep = img->widthStep;
    src2->widthStep = img->widthStep;
    uchar* tmp1;
    uchar* tmp2;
    src1->imageData = img->imageData + 10 * img->widthStep + 5 * img->nChannels;
    src2->imageData = img->imageData + 60 * img->widthStep + 50 * img->nChannels;
    //cvAddS(src1, cvScalar(0), src1);
    //cvAddS(src2, cvScalar(0), src2);
    cvNot(src1, src1);
    cvNot(src2, src2);

    cvReleaseImageHeader(&src1);
    cvReleaseImageHeader(&src2);
    //cvNot(img, img);
    cvNamedWindow("main", 1);
    cvShowImage("main", img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("main");
    return 0;
}

 使用cvCmp()创建一个掩码。加载一个真实的图像。使用cvSplit()将图像分割成红、绿、蓝三个通道图像。
  a.找到并显示绿图
  b.克隆这个绿图(分别命名为clone1和clone2)
  c.求出这个绿色平面的最大值和最小值
  d.将clone1的所有元素赋值为thresh=(unsigned char)((最大值-最小值)/2.0)
  e.将clone1所有元素赋值为0,调用函数cvCmp(green_image,clone1,clone2,CV_CMP_GE)
  f.最后,使用cvSubs(green_image,thresh/2,green_image,clone2)函数并显示结果

#include <cv.h>
#include <highgui.h>
int main()
{
    IplImage *img = cvLoadImage("3.jpg", 1);
    cvNamedWindow("img", 1);
    cvShowImage("img", img);
    IplImage *test,*img1,*G_img,*R_img,*B_img;
    test = cvCreateImage(cvSize(img->width, img->height), img->depth, 1);
    img1 = cvCreateImage(cvSize(img->width, img->height), img->depth, 1);

    G_img = cvCreateImage(cvSize(img->width, img->height), img->depth, 3);
    R_img = cvCreateImage(cvSize(img->width, img->height), img->depth, 3);
    B_img = cvCreateImage(cvSize(img->width, img->height), img->depth, 3);
    cvSplit(img, test, 0, 0, 0);

    CvScalar scalar;
    for (int i = 0; i < img->nChannels; i++)
    {
        scalar.val[0] = 0x1;
    }
    for (int i = 0; i < img->height; i++)
    {
        for (int j = 0; j < img->width; j++)
        {
            cvSet2D(img1, i, j, scalar);
        }
    }
    cvMerge(img1, test, img1, 0, G_img);
    cvMerge(img1, img1, test, 0, R_img);
    cvMerge(test, img1, img1, 0, B_img);
    cvNamedWindow("GREEN", 1);
    cvShowImage("GREEN", G_img); //显示绿图
    cvNamedWindow("RED", 1);
    cvShowImage("RED", R_img);
    cvNamedWindow("BLUE", 1);
    cvShowImage("BLUE", B_img);

    IplImage *clone1, *clone2;
    clone1 = cvCloneImage(test);
    clone2 = cvCloneImage(test);
    double mmax, mmin;
    cvMinMaxLoc(test, &mmin, &mmax);//找出最大值和最小值
    printf("mmin = %d,mmax = %d
", mmin, mmax);
    double thresh = (mmax - mmin) / 2;
    cvSet(clone1, cvScalar(thresh));//将clone1 的所有元素赋值thresh
    cvZero(clone2);                    //将clone1 的所有元素赋值0
    cvCmp(test, clone1, clone2, CV_CMP_GE);
    cvNamedWindow("clone2", 1);
    cvShowImage("clone2", clone2);
    cvSubS(test, cvScalar(thresh / 2), test, clone2);
    cvNamedWindow("test", 1);
    cvShowImage("test", test);
    cvWaitKey();
    cvReleaseImage(&img);
    cvReleaseImage(&test);
    cvReleaseImage(&img1);
    cvReleaseImage(&G_img);
    cvReleaseImage(&clone1);
    cvReleaseImage(&clone2);
    cvDestroyAllWindows();
    return 0;
}

原文地址:https://www.cnblogs.com/chenyang920/p/5349993.html