1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <opencv2/core.hpp>
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <opencv2/core/utility.hpp>
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencv2/imgcodecs.hpp"
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <opencv2/highgui.hpp>
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <iostream>
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <sstream>
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace std;
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace cv;
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void help()
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cout
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "\n--------------------------------------------------------------------------" << endl
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "This program shows how to scan image objects in OpenCV (cv::Mat). As use case"
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << " we take an input image and divide the native color palette (255) with the "  << endl
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "input. Shows C operator[] method, iterators and at function for on-the-fly item address calculation."<< endl
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "Usage:"                                                                       << endl
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "./howToScanImages imageNameToUse divideWith [G]"                              << endl
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "if you add a G parameter the image is processed in gray scale"                << endl
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << "--------------------------------------------------------------------------"   << endl
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << endl;
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceC(Mat& I, const uchar* table);
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceIterator(Mat& I, const uchar* table);
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceRandomAccess(Mat& I, const uchar * table);
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint main( int argc, char* argv[])
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    help();
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (argc < 3)
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cout << "Not enough parameters" << endl;
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return -1;
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat I, J;
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( argc == 4 && !strcmp(argv[3],"G") )
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        I = imread(argv[1], IMREAD_GRAYSCALE);
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        I = imread(argv[1], IMREAD_COLOR);
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (I.empty())
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cout << "The image" << argv[1] << " could not be loaded." << endl;
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return -1;
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //! [dividewith]
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int divideWith = 0; // convert our input string to number - C++ style
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    stringstream s;
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    s << argv[2];
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    s >> divideWith;
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!s || !divideWith)
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cout << "Invalid number entered for dividing. " << endl;
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return -1;
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uchar table[256];
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (int i = 0; i < 256; ++i)
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       table[i] = (uchar)(divideWith * (i/divideWith));
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //! [dividewith]
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int times = 100;
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    double t;
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = (double)getTickCount();
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (int i = 0; i < times; ++i)
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Mat clone_i = I.clone();
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        J = ScanImageAndReduceC(clone_i, table);
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = 1000*((double)getTickCount() - t)/getTickFrequency();
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t /= times;
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cout << "Time of reducing with the C operator [] (averaged for "
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         << times << " runs): " << t << " milliseconds."<< endl;
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = (double)getTickCount();
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (int i = 0; i < times; ++i)
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Mat clone_i = I.clone();
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        J = ScanImageAndReduceIterator(clone_i, table);
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = 1000*((double)getTickCount() - t)/getTickFrequency();
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t /= times;
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cout << "Time of reducing with the iterator (averaged for "
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << times << " runs): " << t << " milliseconds."<< endl;
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = (double)getTickCount();
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (int i = 0; i < times; ++i)
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Mat clone_i = I.clone();
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ScanImageAndReduceRandomAccess(clone_i, table);
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = 1000*((double)getTickCount() - t)/getTickFrequency();
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t /= times;
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cout << "Time of reducing with the on-the-fly address generation - at function (averaged for "
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << times << " runs): " << t << " milliseconds."<< endl;
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //! [table-init]
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat lookUpTable(1, 256, CV_8U);
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uchar* p = lookUpTable.ptr();
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < 256; ++i)
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        p[i] = table[i];
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //! [table-init]
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = (double)getTickCount();
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (int i = 0; i < times; ++i)
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //! [table-use]
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        LUT(I, lookUpTable, J);
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //! [table-use]
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = 1000*((double)getTickCount() - t)/getTickFrequency();
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t /= times;
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cout << "Time of reducing with the LUT function (averaged for "
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        << times << " runs): " << t << " milliseconds."<< endl;
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-c]
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceC(Mat& I, const uchar* const table)
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // accept only char type matrices
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(I.depth() != sizeof(uchar));
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int channels = I.channels();
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int nRows = I.rows;
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int nCols = I.cols * channels;
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (I.isContinuous())
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nCols *= nRows;
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nRows = 1;
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i,j;
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uchar* p;
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < nRows; ++i)
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        p = I.ptr<uchar>(i);
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for ( j = 0; j < nCols; ++j)
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            p[j] = table[p[j]];
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return I;
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-c]
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-iterator]
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // accept only char type matrices
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(I.depth() != sizeof(uchar));
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int channels = I.channels();
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch(channels)
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 1:
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            MatIterator_<uchar> it, end;
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it)
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *it = table[*it];
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 3:
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            MatIterator_<Vec3b> it, end;
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it)
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*it)[0] = table[(*it)[0]];
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*it)[1] = table[(*it)[1]];
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*it)[2] = table[(*it)[2]];
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return I;
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-iterator]
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-random]
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // accept only char type matrices
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(I.depth() != sizeof(uchar));
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int channels = I.channels();
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch(channels)
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 1:
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( int i = 0; i < I.rows; ++i)
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( int j = 0; j < I.cols; ++j )
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    I.at<uchar>(i,j) = table[I.at<uchar>(i,j)];
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 3:
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         Mat_<Vec3b> _I = I;
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         for( int i = 0; i < I.rows; ++i)
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( int j = 0; j < I.cols; ++j )
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler               {
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                   _I(i,j)[0] = table[_I(i,j)[0]];
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                   _I(i,j)[1] = table[_I(i,j)[1]];
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                   _I(i,j)[2] = table[_I(i,j)[2]];
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         I = _I;
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         break;
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return I;
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//! [scan-random]
231