image.cpp

candidate corrected version (after documentation of the defect would be removed) - Ben Ginsberg, 2011-04-13 12:33 pm

Download (6.1 kB)

 
1
#include "cv.h" // include standard OpenCV headers, same as before
2
#include "highgui.h"
3
#include "ml.h"
4
#include <stdio.h>
5
#include <iostream>
6
#include <opencv2/flann/flann.hpp>
7
8
using namespace cv; // all the new API is put into "cv" namespace. Export its content
9
using namespace std;
10
using namespace cv::flann;
11
12
void help()
13
{
14
        cout <<
15
        "\nThis program shows how to use cv::Mat and IplImages converting back and forth.\n"
16
        "It shows reading of images, converting to planes and merging back, color conversion\n"
17
        "and also iterating through pixels.\n"
18
        "Call:\n"
19
        "./image [image-name Default: lena.jpg]\n" << endl;
20
}
21
22
// enable/disable use of mixed API in the code below.
23
#define DEMO_BRANCH_1      0 // default 1: this was "#if 1" (constant) in the original file
24
#define DEMO_MIXED_API_USE 1 // default 1
25
26
/*
27
**
28
**  Compilation Success as a function of macro constants:
29
**
30
**  DEMO_BRANCH_1 DEMO_MIXED_API_USE COMPILE_SUCCESS
31
**  0             *                  0 [see Note 1]
32
**  1             0                  1
33
**  1             1                  1
34
**
35
**  Note 1:
36
**  image.cpp: In function 'int main(int, char**)':
37
**  image.cpp:120: error: call of overloaded 'Mat_(cv::MatExpr)' is ambiguous
38
**  /lib-${ARCH}/opencv-2.2/include/opencv2/core/mat.hpp:794: note: candidates are: cv::Mat_<_Tp>::Mat_(const cv::Mat_<_Tp>&) [with _Tp = unsigned char]
39
**  /lib-${ARCH}/opencv-2.2/include/opencv2/core/mat.hpp:791: note:                 cv::Mat_<_Tp>::Mat_(const cv::Mat&) [with _Tp = unsigned char]
40
**  This however was fixed by casting the matrix expression to (const Mat_<uchar>&),
41
**  in accordance with the first candidate given above.
42
*/
43
44
int main( int argc, char** argv )
45
{
46
        help();
47
    const char* imagename = argc > 1 ? argv[1] : "lena.jpg";
48
#if DEMO_MIXED_API_USE
49
    Ptr<IplImage> iplimg = cvLoadImage(imagename); // Ptr<T> is safe ref-conting pointer class
50
    if(iplimg.empty())
51
    {
52
        fprintf(stderr, "Can not load image %s\n", imagename);
53
        return -1;
54
    }
55
    Mat img(iplimg); // cv::Mat replaces the CvMat and IplImage, but it's easy to convert
56
    // between the old and the new data structures (by default, only the header
57
    // is converted, while the data is shared)
58
#else
59
    Mat img = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function
60
    if(img.empty())
61
    {
62
        fprintf(stderr, "Can not load image %s\n", imagename);
63
        return -1;
64
    }
65
#endif
66
67
    if( !img.data ) // check if the image has been loaded properly
68
        return -1;
69
70
    Mat img_yuv;
71
    cvtColor(img, img_yuv, CV_BGR2YCrCb); // convert image to YUV color space. The output image will be created automatically
72
73
    vector<Mat> planes; // Vector is template vector class, similar to STL's vector. It can store matrices too.
74
    split(img_yuv, planes); // split the image into separate color planes
75
76
#if DEMO_BRANCH_1 // was: #if 1
77
    // method 1. process Y plane using an iterator
78
    MatIterator_<uchar> it = planes[0].begin<uchar>(), it_end = planes[0].end<uchar>();
79
    for(; it != it_end; ++it)
80
    {
81
        double v = *it*1.7 + rand()%21-10;
82
        *it = saturate_cast<uchar>(v*v/255.);
83
    }
84
85
    // method 2. process the first chroma plane using pre-stored row pointer.
86
    // method 3. process the second chroma plane using individual element access
87
    for( int y = 0; y < img_yuv.rows; y++ )
88
    {
89
        uchar* Uptr = planes[1].ptr<uchar>(y);
90
        for( int x = 0; x < img_yuv.cols; x++ )
91
        {
92
            Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);
93
            uchar& Vxy = planes[2].at<uchar>(y, x);
94
            Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128);
95
        }
96
    }
97
98
#else//DEMO_BRANCH_1=0
99
    Mat noise(img.size(), CV_8U); // another Mat constructor; allocates a matrix of the specified size and type
100
    randn(noise, Scalar::all(128), Scalar::all(20)); // fills the matrix with normally distributed random values;
101
                                                     // there is also randu() for uniformly distributed random number generation
102
    GaussianBlur(noise, noise, Size(3, 3), 0.5, 0.5); // blur the noise a bit, kernel size is 3x3 and both sigma's are set to 0.5
103
104
    const double brightness_gain = 0;
105
    const double contrast_gain = 1.7;
106
#if DEMO_MIXED_API_USE
107
    // it's easy to pass the new matrices to the functions that only work with IplImage or CvMat:
108
    // step 1) - convert the headers, data will not be copied
109
    IplImage cv_planes_0 = planes[0], cv_noise = noise;
110
    // step 2) call the function; do not forget unary "&" to form pointers
111
    cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1, -128 + brightness_gain, &cv_planes_0);
112
#else//DEMO_MIXED_API_USE=0
113
    addWeighted(planes[0], contrast_gain, noise, 1, -128 + brightness_gain, planes[0]);
114
#endif//DEMO_MIXED_API_USE
115
    const double color_scale = 0.5;
116
    // Mat::convertTo() replaces cvConvertScale. One must explicitly specify the output matrix type (we keep it intact - planes[1].type())
117
    planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128*(1-color_scale));
118
    // alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here).
119
    // This expression will not create any temporary arrays and should be almost as fast as the above variant
120
    planes[2] = Mat_<uchar>((const Mat_<uchar>&)(planes[2]*color_scale + 128*(1-color_scale))); // NB: was ambiguous, see 'Note 1' above
121
122
    // Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions.
123
    planes[0] = planes[0].mul(planes[0], 1./255);
124
#endif//DEMO_BRANCH_1
125
126
    // now merge the results back
127
    merge(planes, img_yuv);
128
    // and produce the output RGB image
129
    cvtColor(img_yuv, img, CV_YCrCb2BGR);
130
131
    // this is counterpart for cvNamedWindow
132
    namedWindow("image with grain", CV_WINDOW_AUTOSIZE);
133
#if DEMO_MIXED_API_USE
134
    // this is to demonstrate that img and iplimg really share the data - the result of the above
135
    // processing is stored in img and thus in iplimg too.
136
    cvShowImage("image with grain", iplimg);
137
#else
138
    imshow("image with grain", img);
139
#endif
140
    waitKey();
141
142
    return 0;
143
    // all the memory will automatically be released by Vector<>, Mat and Ptr<> destructors.
144
}