Errata

Learning OpenCV 3

Errata for Learning OpenCV 3

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
ePub
Page Loc 15 ~ Loc 23
Before Preface section

The Kindle version does not have the table of contents included in the print version. Maybe other digital version has the same problem. That's hard to search a page where I want to read. Could you add it into an updated version?

Note from the Author or Editor:
The authors were not aware of this. I will pass it on to O'Reilly and hopefully they can fix it.

Anonymous  Jan 24, 2017 
, Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 3
About the Programs in This Book

The code samples that referenced in book are missing under the Essential Links section.

Aleksandr Tischenko  Jul 17, 2016  Dec 09, 2016
PDF
Page 22
First Program

Like many books containing code samples that look superficially easy this one omits build instructions for the examples. This is obviously highly platform dependent nonetheless the book would benefit from at least providing some hints, like a sample one line build command as given below. Also some hints about the library partitioning as well as the header partitioning would be helpful. For example building the video examples in chapter 2 requires different libraries to the canny example. Both can be built with something like: gcc -v example.cpp -I/usr/local/include/ -L/usr/lib/ -lstdc++ -L/usr/local/lib -lopencv_imgcodecs -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_videoio -lopencv_video -lopencv_videostab -o example Not providing any guidance could be a major blocker for some.

hacedor  Sep 09, 2016  Dec 09, 2016
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 23-37
Source code examples

In chapter two, there are a number of small errors that affect the code examples, details follow. Please note that that code on GitHub reflects these changes already. ----- • Example 2-1: ○ Change "Example1" to "Example 2-1" p23 § Note that this appears in three places in the code. Also, where the code is described in detail (pages 24-25), each of these three lines appear again, and this substitution should be made in each of these locations (once on p24, twice on p25). It also appears in the text at the bottom of p24, this also should be changed. • Example 2-2: ○ Change "Example1" to "Example 2-2" p24 § Note that this appears in three places in the code. • Example 2-3: ○ Change "Example3" to "Example 2-3" p26 § Also note that, this substitution must also be made at the middle of p26, just after "in this case, named...", and again lower on page 26, this same substitution needs to be made again in the code 'snipet' just above the words "Once inside of…". ○ Insert a line reading "using namespace std;" after the second "#include" line and before the line beginning with "int main(…" p26 ○ Change "cv::waitKey(33)" to "(char) cv::waitKey(33)" p26 • Example 2-4: ○ Change "Example2-4" to "Example 2-4" p28 § Note that this appears in four places in the code. § again in code 'snip' in the middle of p30 § again twice in code 'snip' at top of p30 ○ Change "cv::CAP_PROP_FRAME_COUNT" to "CV_CAP_PROP_FRAME_COUNT" p27 § again in code 'snip' at top of p30 ○ Change "cv::CAP_PROP_FRAME_WIDTH" to "CV_CAP_PROP_FRAME_WIDTH" p27 § again in code 'snip' at top of p30 ○ Change "cv::CAP_PROP_FRAME_HEIGHT" to "CV_CAP_PROP_FRAME_HEIGHT" p27 ○ Change "cv::CAP_PROP_POS_FRAMES" to "CV_CAP_PROP_POS_FRAMES" p27 § again in code 'snip' at bottom of p29 § again in text at top of p30 § again in code 'snip' at top of p30 • Example 2-5: ○ Change "Example4-out" to "Example 2-5-out" at bottom of p31 ○ Change "Example2_5-in" to "Example 2-5-in" p32 § Note that this appears in two places in the code. ○ Change "Example2_5-out" to "Example 2-5-out" p32 § Note that this appears in two places in the code. ○ On p32, the line reading "void example2_5( const cv::Mat & image ) {" should be changed to "int main( int argc, char** argv ) {" should be replaced by the following give lines: (note that second line is blank, third through fifth lines are double space indent.) """ int main( int argc, char** argv ) { // Load an image specified on the command line. // cv::Mat image = cv::imread(argv[1],-1); """ • Example 2-6: ○ "img = cv::imread…" should be "img1 = cv::imread…" ○ Change "Example1" to "Example 2-6-in" p33 § Note that this appears in two places in the code. ○ Change "Example2" to "Example 2-6-out" p33 § Note that this appears in two places in the code. • Example 2-10: ○ Change "Example2_10" to "Example 2-10" p35 • Example 2-11: ○ Change "Example2_11" to "Example 2-11" p36, p37 § Note that this appears in two places in the code. ○ Change "cv::WARP_FILL_OUTLIERS" to "CV_WARP_FILL_OUTLIERS" p37 ○ Change "cv::CAP_PROP_FRAME_FPS" to "CV_CAP_PROP_FRAME_FPS" p36 ○ Change "cv::CAP_PROP_FRAME_WIDTH" to "CV_CAP_PROP_FRAME_WIDTH" p36 ○ Change "cv::CAP_PROP_FRAME_HEIGHT" to "CV_CAP_PROP_FRAME_HEIGHT" p37 ○ Change "cv::waitKey(10)" to "(char) cv::waitKey(33)"

Adrian Kaehler
Adrian Kaehler
 
Feb 17, 2017  Dec 15, 2017
Printed, PDF
Page 26
Last paragraph

The text "Once inside of the while() loop" should be changed to "Once inside of the main loop". Please note that the word "while()" is in 'inline code' font, while the replacement word 'main' should be in 'normal body' font.

Adrian Kaehler
Adrian Kaehler
 
Feb 18, 2017  Dec 15, 2017
PDF
Page 31
Second paragraph after "A Simple Transformation" header

In the description text it is stated 'We can start by creating a new window called "Example4-out"', however in the code for the example (2-5) the window is called Example2_5-out.

Note from the Author or Editor:
Submitter is correct, the phrase '...new window called "Example4-out", where we can...' should be changed so that 'Example4' is replaced by 'Example5'.

Ira Burton  Dec 20, 2016  Jan 20, 2017
Printed
Page 31
2nd paragraph, in bold

"At the bottom of the while loop,"... in reference to the code example its actually a for loop.

Note from the Author or Editor:
The submitter is correct. On page 31, the word "while" appears twice, once in the context of "In the while loop, in addition...", and again in the context of "At the bottom of the while loop..." In both cases, the word 'while' is in inline-code font. In both cases, the word "while" should be replaced by the word "main" *AND* the formatting of the word should be changed to Body-Text so that this word does not appear special relative to the words around it.

Eric Lovejoy  Jan 06, 2017  Jan 20, 2017
Printed
Page 33
Bottom of code block for Example 2-6

Remove semicolon from final line of code block: '};' should be changed to just '}'

Adrian Kaehler
Adrian Kaehler
 
Feb 19, 2017  Dec 15, 2017
Printed
Page 34, 35
bottom page 34, top page 35

the variable intensity is set, but not used in the example. from context, I cannot guess how it might be used. (Sorry, Im Learning OpenCV3) //***New issue in same example::: on these lines: cout << "The Gray pixel there is: " << (unsigned int)img_gray.at<uchar>(x,y) << "\n"; x/=4; y/=4; cout << "Pyramid pixel there is: " << (unsigned int)img_pyr1.at<uchar>(x,y) << "\n"; x,y are reversed y,x in the book, example2-9 perhaps it was intentional, but Im thinking not.

Note from the Author or Editor:
tl;dr: One small change, error is actually in the comment. Relating to the "intensity" variable: this is just pedagogical, it was intended to make clear that the intensity, as a vector, can be extracted with using at<cv::Vec3b>, while later on, the use of at<uchar> is shown as an alternative. at<> access and "y, x": The correct access is image.at<uchar>(y,x). (The logic here has to do with the "running speed" of an index, i.e. if you were to access a pixel in a byte array, you might do something like: pixel = y*row_size+x. And in a three dimensional array z*plane_size+y*row_size+x. So this is in keeping with the idea of a "base-N" number as a way of thinking about an image or image tensor.) However: There is an error, which you might not have noticed, which is that in the comment at the bottom or page 34, the accessor actually does say "img_rgb.at< cv::Vec3b >(x,y)[0]". It is the comment that is wrong. This should be changed to read "y,x" instead of "x,y".

Eric Lovejoy  Jan 19, 2017  Dec 15, 2017
PDF
Page 34
Example2-8

it is missing the prefix "COLOR_" when converting the image color: cv::cvtColor( img_rgb, img_gry, cv::BGR2GRAY );

Note from the Author or Editor:
The submitter is correct. * Please change "cv::BGR2GRAY" to "cv::COLOR_BGR2GRAY" in the middle of p34.

João Ferreira Nunes  Jan 26, 2017  Dec 15, 2017
PDF
Page 36
code snippet for Example 2-11

A window is being created for the Example 2-11, but is named "Example2_10" throughout the whole snippet. Of course this does not prevent the code from compiling nor running, but to be consistent the window should be named "Example2_11".

Luca Manzari  Oct 18, 2016  Dec 09, 2016
PDF
Page 37
beginning of the page, in the code snippet of Example 2-11

Point2f belongs to the namespace cv, and as such it should be referred to as cv::Point2f. The code as it is will not compile since Point2f is undeclared in the scope of the main function. In other words, the 12th line of code of page 37 should read cv::Point2f( // Centerpoint for log-polar transformation instead of Point2f( // Centerpoint for log-polar transformation

Luca Manzari  Oct 18, 2016  Dec 09, 2016
PDF
Page 44
last but one paragraph

Sentence suggested the existence of types Point2s and Point3s based on 'short' primitive, which there are not (at least in OpenCV 3.2)

Note from the Author or Editor:
Thank you. This is correct. The text does make it seem like there should be such a type. * Delete text ", s is a short integer" from comma separated list.

Anonymous  Jan 24, 2017  Dec 15, 2017
PDF
Page 53
footnote #7

Conversely to what is there stated, there's no std::smart_ptr<> class in C++ STL. Indeed, cv::Ptr<> has similarities with std::shared_ptr<> class (introduced in C++11 standard).

Note from the Author or Editor:
The submitter is correct. The text should read "std::shared_ptr<>", not "std::smart_ptr<>" (as it does in the case for the Boost library). * Change "std::shared_ptr<>" to "std::smart_ptr<>" in footnote 7.

Anonymous  Jan 24, 2017  Dec 15, 2017
Printed
Page 60
Table 3-10

cv::Ceil()a should probably be cv::Ceil(a) or cv::Ceil(x), because the right column then states the function as referenced to x.

Note from the Author or Editor:
What the reader is referring to is a superscript, which is a sort of footnote, that references a note at the bottom of table 3-10. The "a" to which he refers is a bit unclear here because that note does not appear until the following page 61. Is it possible to 1) change the "a" to a more standard footnote marker (like the number "1"), and 2) rearrange the text so that the note in question actually appears on page 60 as a standard footnote?

Eric Lovejoy  Jan 07, 2017  Jan 20, 2017
Printed
Page 69
exercise 1, page 69, end of chapter 3.

in OpenCV3, cxtypes.h doesn't exist. ( I recognize this was a version 1 header.) the modern replacement, would be "opencv2/core/types_c.h" If this varies, on windows machines, I have no way to check, but in Linux: $ locate cxtypes.h $ locate types_c.h ~/Downloads/opencv-3.2.0/modules/core/include/opencv2/core/types_c.h ~/Downloads/opencv-3.2.0/modules/imgproc/include/opencv2/imgproc/types_c.h ~/opencv/build/junk/types_c.h.junk ~/opencv/modules/core/include/opencv2/core/types_c.h ~/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h /usr/include/opencv2/core/types_c.h /usr/include/opencv2/imgproc/types_c.h /usr/local/include/opencv2/core/types_c.h /usr/local/include/opencv2/imgproc/types_c.h

Note from the Author or Editor:
The reader is exactly correct. the text ".../opencv/cxcore/include/cxtypes.h" should be changed to read "...opencv/modules/core/include/opencv2/core/types_c.h"

Eric Lovejoy  Jan 17, 2017  Dec 15, 2017
Printed
Page 82
Example 4-1/2/3/4

* The code in Example 4-1 is formatted in a way that makes it rather unclear. Please make the following changes: - Insert before the first line of code in Example 4-1 the following: "int main( int argc, char** argv ) {" (on it's own line, then followed by a single blank line.) - Indent the first code block. - Insert a blank line at the end of the second code block, and another line containing only a single '}'. - Note that the indentations of the code blocks should match those of "normal" code indentation. (For example, see Example 2-6 on p33.) Note that the 'int main...' line at the beginning and the '}' line at the end are not indented. * Example 4-2 has the same issues. Please make the same changes as Example 4-1 above: i.e. Add "int main..." line at the top, and a blank line. Add a blank line and a '}' line at the end, and indent all of the code in between. * In the code block that spans the bottom of p83 to the top of p84 (which is *not* part of example 4-2), has an inconsistant indenting with the format of the book. Please change the indenting on the subblocks to match the standard two whitespace indent used throughout the rest of the book. * Example 4-3 has the same issues as the prior examples. Please make the same changes as Example 4-1 above: i.e. Add "int main..." line at the top, and a blank line. Add a blank line and a '}' line at the end, and indent all of the code in between.

Adrian Kaehler
Adrian Kaehler
 
Feb 19, 2017  Dec 15, 2017
PDF
Page 87
cv::completSymm() function

End of description states "If the flag lowerToUpper is true, then the elements from the upper triangle are copied into the lower triangle instead" There may be some obscure reasoning or non obvious logic that supports this but shouldn't this be lower to upper?

Dave Burke  Aug 16, 2016  Dec 09, 2016
PDF
Page 87
cv::completeSymm()

Two exact equations are given, both for 'lowerToUpper' being false. I suppose one should be changed to fit the case that 'lowerToUpper' equals true

Philipp Deibert  Sep 22, 2016  Dec 09, 2016
PDF
Page 93
cv::exp()

The description of cv::exp() uses the argumentname src1 instead of src. Just a small typo there.

Philipp Deibert  Sep 24, 2016  Dec 09, 2016
PDF
Page 101-102
cv::minMaxIdx() and cv::minMaxLoc()

It says for both minMaxLoc() and minMaxIdx() that they should only be used on two-dimensional arrays and that minMaxLoc() can also be used on n-dimensional SparseMats. The OpenCV documentation however implies that minMaxIdx() can be used on n-dimensional arrays in gerneral: "minIdx - pointer to the returned minimum location (in nD case); [...] maxIdx - pointer to the returned minimum location (in nD case);". For minMaxLoc() it says "minLoc - pointer to the returned minimum location (in 2D case); [...] maxLoc - pointer to the returned minimum location (in 2D case);". It is not clear to me if something got mixed up in the text and if not I would suggest clearification on the difference between both operations.

Philipp Deibert  Sep 24, 2016  Dec 09, 2016
Printed, PDF
Page 103, 114, 123 125 326 327 368 435 460 461 462 464 760

(1) Everywhere "U8" appears, it should be "8U". example: CV_U8 => CV_8U (2) Everywhere cv::U8 appears, it should be CV_8U example: cv::U8 => CV_8U

Gary Rost Bradski
Gary Rost Bradski
 
Jul 06, 2017  Aug 20, 2021
PDF
Page 106
cv::normalize()

The description refers to the argument dtype as rtype in two places

Philipp Deibert  Sep 25, 2016  Dec 09, 2016
PDF
Page 111
cv::solve()

In the description for the different values for method the variable names src1 and src2 are being used. It would be clearer if it would be mentioned which name is refering to which argument.

Philipp Deibert  Sep 27, 2016  Dec 09, 2016
PDF
Page 112-113
cv::sort(), cv::sortIdx(), cv::sqrt(),

It says that the functions sort(), sortIdx() and sqrt() all take an argument dst of type InputtArray, although they should be of type OutputArray, which would only make sense.

Philipp Deibert  Sep 27, 2016  Dec 09, 2016
PDF
Page 112
cv::solveCubic() description

Before the double lined text: "...how may real roots the polynomial has" should read: "...how many real roots the polynomial has" Inside the double lined text warning, last sentence: "In cv::solveCubic(), the highest order coefficients come last, while in cv:: solvePoly(), the highest coefficients come last." I'm assuming in one of these should read, "the highest order should come first" The reason for a warning!

Dave Burke  Aug 16, 2016  Dec 09, 2016
PDF
Page 120
Footnote 2

Footnote 2 refers to cv::fillComvexPolyfillConvexPoly(). Probably fillConvexPoly() was meant instead.

Philipp Deibert  Sep 28, 2016  Dec 09, 2016
PDF
Page 123
Below table 6.3

"Any of the font names listed in can also be combined....." I'm guessing Table 6.3 is missing!

Dave Burke  Aug 16, 2016  Dec 09, 2016
PDF
Page 130
cv::SVD::solveZ()

definition shows z as return array.. Text below math function z=.... in two places refers to y. End of first sentence "...place the solution in the array y." and last sentence"..... then the return value y will be a vector"

Dave Burke  Aug 16, 2016  Dec 09, 2016
PDF
Page 137
Table 8-1

cv::IMREAD_UNCHANGED is said to be equivalent to 'IMREAD_ANYCOLOR | IMREAD_UNCHANGED'. Given by the name i would guess that it should be 'IMREAD_ANYCOLOR | IMREAD_ANYDEPTH' instead. In any case the current description of IMREAD_UNCHANGED does not make any sense.

Philipp Deibert  Sep 29, 2016  Dec 09, 2016
PDF
Page 141
Under cv::reduce()

The comment for the 3rd parameter (dim) of the cv::reduce() prototype says: "Reduction direction (1) to row, (0) to col" However, the table below, and the official documentation says the opposite.

RIH  Oct 06, 2016  Dec 09, 2016
PDF
Page 170
CV::repeat()

The following definition, p145 on Dec2016 verson, cv::repeat() void cv::repeat( cv::InputArray src, // Input 2-dimensional array int nx, // Copies in x-direction int ny, // Copies in y-direction cv::OutputArray dst // Result array ); cv::Mat cv::repeat( // Return result array cv::InputArray src, // Input 2-dimensional array int nx, // Copies in x-direction int ny // Copies in y-direction ); I was using this function to build an image mask and found that the width and height values of the resultant matrix were transposed. OpenCV web page shows that the function parameters nx and ny should be the other way round ny, nx as follows. Mat repeat(const Mat& src, int ny, int nx) (C++ function, in Operations on Arrays) void repeat(InputArray src, int ny, int nx, OutputArray dst) (C++ function, in Operations on Arrays)

Note from the Author or Editor:
This is correct. The lines for Nx and Ny are incorrectly transposed in the text. * Please reverse the order of the lines containing "int nx, // Copies in x-direction" and "int ny, // Copies in y-direction" in the code describing cv::repeat() at the bottom of the page. Please note that the error appears twice, once in each prototype for cv::repeat(). p145

Dave Burke  Jan 24, 2017  Dec 15, 2017
PDF
Page 189
footnote #4

reported ' vector<int>&' should be ' vector<uchar>&"

Note from the Author or Editor:
I agree, this would be more clear. * Change "<int>" to "<uchar>" in footnote.

Anonymous  Jan 27, 2017  Dec 15, 2017
PDF
Page 198
3rd paragraph

FileStorage::FileStorage(); should be cv::FileStorage::FileStorage(); It's more clear.

Note from the Author or Editor:
Reader is correct * Please change "FileStorage::FileStorage" to "cv::FileStorage::FileStorage" in code example 'snips'. Please note that this correction needs to be made three times, once right after "Writing to a cv::FileStorage", and twice just before "Once you have opened...". p198

Kouichi MATSUDA  Feb 03, 2017  Dec 15, 2017
Printed
Page 222 ~ 224
2nd and 3rd paragraphs in 222 page and more

The book says cv::namedWindow() takes cv::GUI_NORMAL, cv::GUI_EXTENDED as second parameter. But in reality, those are cv::WINDOW_GUI_NORMAL and cv::WINDOW_GUI_EXPANDED.

Note from the Author or Editor:
Comment is only partially correct. The correct usage is to use CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE to determine how the window is sized, and CV_GUI_NORMAL and CV_GUI_AUTOSIZE to determine if the enhanced Qt based interface is to be enabled. It should be noted that in the case of the former two, it is also acceptable (and even preferred) to use cv::WINDOW_NORMAL or cv::WINDOW_AUTOSIZE (i.e. the cv:: namespace versions), but for the latter pair, the library has not yet been modified so as to make in "in namespace" version available. However, there is a different error, which is that the book says cv::GUI_EXTENDED when the correct usage is CV_GUI_EXPANDED. Note that The book says "EXTENDED" when the correct flag is "EXPANDED", but there is also the more subtle issue of the "cv::" namespace version, described in the book, not yet being released in the library. * Change cv::GUI_EXTENDED to CV_GUI_EXPANDED in both places it appears on p222, and in the third paragraph on p224. Also change cv::GUI_NORMAL to CV_GUI_NORMAL in the second paragraph on p222, and in the first paragraph on p223.

Seunghoon Jung  Feb 12, 2017  Dec 15, 2017
Printed
Page 231
2nd paragraph and 2nd c++ code segment

To register OpenGL callback function, the book teaches to use cv:createOpenGLCallback() function. But, in the OpenCV reference site on OPpenCV 3.2.0, there is no such function. In the OpenCV homepage, there is just setOpenGlDrawCallback() function.

Note from the Author or Editor:
User is correct. * Change "createOpenGLCallback() to setOpenGLCallback()" where it appears in the second paragraph and in the second code 'snip' on p231.

Seunghoon Jung  Feb 12, 2017  Dec 15, 2017
PDF
Page 236
line 15 (actually 4th line of the paragraph after code snippet)

'cv_hreader_to_qt_image' should be instead 'cv_header_to_qt_image' as defined in preceding code snippet

Note from the Author or Editor:
Reader is correct. * Change "cv_hreader_to_qt_image" to "cv_header_to_qt_image" (i.e. delete the spurious 'r') (1/4 of the way down p236)

Anonymous  Jan 30, 2017  Dec 15, 2017
PDF
Page 259
The last paragraph

"Note the calling-convention comments at the top of the code in Example 10-2; the parameters used for Figure 10-5 were:" Example 10-2 should be 10-3. "the calling-convention comments at the top of the code" was a copy&paste from the previous version. It should be "calling-convention is in the string in if-clause below main()" or something like that.

Note from the Author or Editor:
The reader is correct * Please change "Example 10-2" to "Example 10-3" in both places where it appears in the last paragraph on p259. * Also please change "comments" to "messages" in the last line of the same paragraph.

Kouichi MATSUDA  Feb 06, 2017  Dec 15, 2017
PDF
Page 260
The example 10-3

To build example 10-3, you have to add the following lines, or it won't compile: At top (missing): #include <opencv2/opencv.hpp> #include <cstdlib> And a constant has changed so that you must replace: cv::Mat Igray = cv::imread(argv[6], cv::LOAD_IMAGE_GRAYSCALE); with: cv::Mat Igray = cv::imread(argv[6], cv::IMREAD_GRAYSCALE);

Gary R Bradski  May 20, 2017  Aug 20, 2021
Printed
Page 270
Bottom line

For the Sobel operator, it can take a kernel size (ksize parameter) equal 1. But the book does not explain what a derivative filter of size 1 means. The following sentences should be added: In all cases except one, the 𝚔𝚜𝚒𝚣𝚎×𝚔𝚜𝚒𝚣𝚎 separable kernel is used to calculate the derivative. When 𝚔𝚜𝚒𝚣𝚎 = 𝟷, the 3×1 or 1×3 kernel is used (that is, no Gaussian smoothing is done). ksize = 1 can only be used for the first or the second x- or y- derivatives.

Gary Rost Bradski
Gary Rost Bradski
 
Mar 03, 2017  Aug 20, 2021
PDF
Page 271
1st line

"The ksize parameter should be odd and is the width (and the height) of the filter to be used. Currently, aperture sizes up to 31 are supported. " The "aperture sizes" should be ksize.

Note from the Author or Editor:
In this context, "kernel" and "aperture" are used interchangeably in the literature. We agree however that changing from one to the other in this way is more confusing than helpful. * Change "aperture sizes" to "kernel sizes" at the top of page 271.

Kouichi MATSUDA  Feb 08, 2017  Dec 15, 2017
PDF
Page 273
definition of cv::Laplacian function

4th argument type is 'int' (not cv::Size)

Note from the Author or Editor:
Reader is correct * Please change "cv::Size ksize" to "int ksize"

Anonymous  Jan 30, 2017  Dec 15, 2017
Printed
Page 281
next to last line.

"ning" -> "opening"

Douglas Morgan  Nov 07, 2017  Dec 15, 2017
Printed
Page 303
2nd paragraph

"or objects of type" should be "of objects of type".

Douglas Morgan  Nov 07, 2017  Dec 15, 2017
PDF
Page 312
1st paragraph

"You can combine these methods of setting the map_matrix to obtain, for example, an image that is rotated, scaled, and warped." "map_matrix" should be "M" or "map matrix M".

Note from the Author or Editor:
Reader is correct, this is confusing and should be changed. * Change "map_matrix" to "map matrix M". Please note that "map matrix" should be in Body font, while "M" should be in Inline Code font.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 314
3rd paragraph

"As with the affine transformation, for filling the map_matrix in the preceding code," "map_matrix" should be "M" or "map matrix".

Note from the Author or Editor:
Agreed, this is confusing and should be changed. * Please change "map_matrix" to "map matrix" in the second paragraph on p314. Also, please change the font from Inline Code to Body.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 315
3rd paragraph

"These arrays should be two- or three-channel arrays. The matrix mat can be either a " "mat" should be "mtx" or the prototype should be "mat".

Note from the Author or Editor:
The reader is correct. * Please change "The matrix mat can be..." to "The matrix mtx can be...". Please note that 'mat' was, and 'mtx' should still be, in Inline Code font.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 318
2nd paragraph

"cvCartToPolar( dx_img, dy_img, img_mag, img_angle, 1 ). We would then fill a" should be "cv::cartToPolar".

Note from the Author or Editor:
Reader is correct. * Please change "cvCartToPolar" to "cv::cartToPolar" near end of second paragraph on p318.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 321
Exercise 3

in chapter 8 ,page 321 "3. Load an interesting image, and then blur it with cv::smooth() using a Gaussian filter. a. Set param1=param2=9. Try several settings of param3 (e.g., 1, 4, and 6). Display the results. b. Set param1=param2=0 before setting param3 to 1, 4, and 6. Display the results. Are they different? Why? c. Use param1=param2=0 again, but this time set param3=1 and param4=9. Smooth the picture and display the results. d. Repeat Exercise 3c but with param3=9 and param4=1. Display the results. e. Now smooth the image once with the settings of Exercise 3c and once with the settings of Exercise 3d. Display the results. f. Compare the results in Exercise 3e with smoothings that use param3=param4=9 and param3=param4=0 (i.e., a 9 × 9 filter). Are the results the same? Why or why not?" as i kown,cv::smooth() is out of use for quite a long time (am i right,i cant find it neither in the code nor in the book) ,then how to solve this problem,and where is the param1?param2?

Gary R Bradski  Jun 30, 2017  Aug 20, 2021
PDF
Page 329
After "Variation: Computing the mean with cv::accumulateWeighted()"

On this page, and many subsequent pages of the April 12th PDF, the equations are completely illegible.

johnbrewer  Apr 19, 2016  Dec 09, 2016
PDF
Page 372
Figure 12-14

The preceding paragraph tells about DARPA Grand Challenge and the figure should contain the image of a road. It contains fruits instead, the copy of the previous figure.

Note from the Author or Editor:
Reader is correct. This is not the correct image. * Locate the correct image and correct this entry.

Anonymous  Jan 29, 2017  Dec 15, 2017
PDF
Page 377
code at page foot

cv::calcHist syntax is repeated twice second C and also STL C++ are missing

Note from the Author or Editor:
The submitter is incorrect that the same text is repeated twice, one prototype applies to the case in which the output is a dense array ("OutputArray"), while the other applies to the case in which the output is a sparse array ("SpraseMat"). However, the submitter *is correct* that a third prototype is missing. Below the first two prototypes that are present, just before the new paragraph beginning "There are three forms of...", there should be a third prototype. Please note that in the text below, detailed formatting is not exactly possible, so please arrange the formatting to match that of the two prototypes that are already present. That prototype should be: void cv::calcHist( cv::InputArrayOfArrays images, // vector of 8U or 32F images const vector<int>& channels, // lists channels to use cv::InputArray mask, // in 'images' count, iff 'mask' nonzero cv::OutputArray hist, // output histogram array const vector<int>& histSize, // hist sizes in each dimension const vector<float>& ranges, // pairs give bin sizes in a flat list bool accumulate = false // if true, add to 'hist', else replace )

Anonymous  Jan 17, 2017  Jan 20, 2017
PDF
Page 381
2nd definition of cv::minMaxLoc function

correct definition is void cv::minMaxLoc ( const SparseMat & a, double * minVal, double * maxVal, int * minIdx = 0, int * maxIdx = 0 )

Note from the Author or Editor:
Reader is correct. * Please change "cv::Point*" to "int*" in both places in which it appears in the function prototype just above the last paragraph on p381.

Anonymous  Feb 10, 2017  Dec 15, 2017
PDF
Page 411
1st paragraph

"tours, where contours[i] will be a specific contour and thus contours[i][j] would refer to a specific vertex in contour[i]). " The last "contour[i]" should be "contours[i]".

Note from the Author or Editor:
Reader is correct. * Please change 'contour[i]' to 'contours[i]' at the end of the first paragraph on p411.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 423
3rd paragraph

void cv::minEnclosingCircle( cv::InputArray points, // Array or vector of 2-dimensional points cv::Point2f& center, // Result location of circle center float& radius // Result radius of circle ); "The input curve is just the usual sequence of points representation. The center and radius variables are variables you will" "curve" should be "points" or intentinal?

Note from the Author or Editor:
Reader is correct, the current wording is unclear and confusing. * Please change "The input curve..." to "The input points..." in the second paragraph on p424. Please also note that 'points' should be in Inline Code font.

Kouichi MATSUDA  Feb 18, 2017  Dec 15, 2017
PDF
Page 431
listing at the top

Data members nu20,... nu03 are normalized central moments rather than Hu invariant moments as is said in comments.

Note from the Author or Editor:
The reader is correct. Please make the change described below: * Change the two lines reading: """ double nu20, nu11, nu02; // second order Hu invariant moments (x3) double nu30, nu21, nu12, nu03; // third order Hu invariant moments (x4) """ to instead read: """ double nu20, nu11, nu02; // second order normalized central (x3) double nu30, nu21, nu12, nu03; // third order normalized central (x4) """

Anonymous  Jan 29, 2017  Dec 15, 2017
PDF
Page 434
The second line

The expression for the second Hu moment (h2) is incorrect - the plus should be changed for the minus.

Note from the Author or Editor:
Reader is correct, see change below: Change "h_{2} = (\nu_{20} + \nu_{02})^{2}" to "h_{2} = (\nu_{20} - \nu_{02})^{2}". (i.e. Change the plus to a minus in the definition of h_2. at the top of page 434.)

Anonymous  Jan 29, 2017  Dec 15, 2017
Printed
Page 439
1st paragraph

"computes representation" should be "computes a representation"

Douglas Morgan  Nov 13, 2017  Dec 15, 2017
PDF
Page 448
Second to last line

int left_to_right = 0 // 1='fixed iteration direction' should read as bool left_to_right = 0 // true='always iteratу from left to right'

Note from the Author or Editor:
Reader is correct. * Please change "int left_to_right = 0 // 1='fixed iteration direction'" to read "bool left_to_right = false // true='fixed iteration direction'".

Anonymous  Jan 30, 2017  Dec 15, 2017
PDF
Page 449
Example 15-1

There are various minor errors in the Example code 15-1, such as the void help( argv ) { function should be void help(char** argv) { But, to make it easy, just replace Example 15-1 with this correct code that compiles and runs: ================ //Example 15-1. Reading out the RGB values of all pixels in one row of a video and // accumulating those values into three separate comma separated files // #include <opencv2/opencv.hpp> #include <iostream> #include <fstream> using namespace std; void help(char** argv ) { cout << "\n" << "Read out RGB pixel values and store them to disk\nCall:\n" << argv[0] <<" avi_file\n" << "\n This will store to files blines.csv, glines.csv and rlines.csv\n\n" << endl; } int main( int argc, char** argv) { // Argument handling // if(argc != 2) { help(argv); return -1; } cv::namedWindow( argv[0], CV_WINDOW_AUTOSIZE ); cv::VideoCapture cap; if((argc < 2)|| !cap.open(argv[1])) { cerr << "Couldn't open video file" << endl; help(argv); cap.open(0); return -1; } //Prepare Output // cv::Point pt1(10,10), pt2(30,30); int max_buffer; cv::Mat rawImage; ofstream b,g,r; b.open("blines.csv"); g.open("glines.csv"); r.open("rlines.csv"); // MAIN PROCESSING LOOP: // for(;;) { cap >> rawImage; if( !rawImage.data ) break; cv::LineIterator it( rawImage, pt1, pt2, 8); for( int j=0; j<it.count; ++j,++it ) { b << (int)(*it)[0] << ", "; g << (int)(*it)[1] << ", "; r << (int)(*it)[2] << ", "; (*it)[2] = 255; // Mark this sample in red } cv::imshow( argv[0], rawImage ); int c = cv::waitKey(10); b << "\n"; g << "\n"; r << "\n"; } // CLEAN UP: // b << endl; g << endl; r << endl; b.close(); g.close(); r.close(); cout << "\n" << "Data stored to files: blines.csv, glines.csv and rlines.csv\n\n" << endl; }

Gary R Bradski  May 23, 2017  Aug 20, 2021
PDF
Page 450
11-th nonempty line

The statement to open stdin cap.open(0); is redundant because main exits anyway.

Note from the Author or Editor:
Reader is correct. In this case, the call is unneeded. It is also somewhat confusing as written. It might have made more sense to call cap.close() in this location. However, because the cv:VideoCapture destructor will automatically call close(), the line can be completely removed. * Delete the line reading "cap.open(0);"

Anonymous  Jan 30, 2017  Dec 15, 2017
PDF
Page 453
Example 15-2

Going through the code, Example 15-2 needed many changes to make it functional, new code appears below: // Example 15-2. Learning a background model to identify foreground pixels #include <opencv2/opencv.hpp> #include <iostream> #include <cstdlib> #include <fstream> using namespace std; // Global storage // // Float, 3-channel images // cv::Mat image; //, rawImage; cv::Mat IavgF, IdiffF, IprevF, IhiF, IlowF; cv::Mat tmp, tmp2, mask; // Float, 1-channel images // vector<cv::Mat> Igray(3); vector<cv::Mat> Ilow(3); vector<cv::Mat> Ihi(3); // Byte, 1-channel image // cv::Mat Imaskt; // Thresholds // float high_thresh = 15.0; //scaling the thesholds in backgroundDiff() float low_thresh = 13.0; // Counts number of images learned for averaging later // float Icount; *** FIRST PART, THEN THERE IS TEXT: p-453: "Next, we create a single "... AND AGAIN REPLACE **** // I is just a sample image for allocation purposes // (passed in for sizing) // void AllocateImages( const cv::Mat& I ) { cv::Size sz = I.size(); IavgF = cv::Mat::zeros(sz, CV_32FC3 ); IdiffF = cv::Mat::zeros(sz, CV_32FC3 ); IprevF = cv::Mat::zeros(sz, CV_32FC3 ); IhiF = cv::Mat::zeros(sz, CV_32FC3 ); IlowF = cv::Mat::zeros(sz, CV_32FC3 ); Icount = 0.00001; // Protect against divide by zero tmp = cv::Mat::zeros( sz, CV_32FC3 ); tmp2 = cv::Mat::zeros( sz, CV_32FC3 ); Imaskt = cv::Mat( sz, CV_32FC1 ); } *** MORE TEXT: P-454 "In the next piece of code..." *** // Learn the background statistics for one more frame // I is a color sample of the background, 3-channel, 8u // void accumulateBackground( cv::Mat& I ){ static int first = 1; // nb. Not thread safe I.convertTo( tmp, CV_32F ); // convert to float if( !first ){ IavgF += tmp; cv::absdiff( tmp, IprevF, tmp2 ); IdiffF += tmp2; Icount += 1.0; } first = 0; IprevF = tmp; } *** THEN MORE TEXT P-455: ... "Once we have accumulated enough" **** void createModelsfromStats() { IavgF *= (1.0/Icount); IdiffF *= (1.0/Icount); // Make sure diff is always something // IdiffF += cv::Scalar( 1.0, 1.0, 1.0 ); setHighThreshold( high_thresh); setLowThreshold( low_thresh); } *** MORE TEXT P-455 ... "These threshold function are:" *** void setHighThreshold( float scale ) { IhiF = IavgF + (IdiffF * scale); cv::split( IhiF, Ihi ); } void setLowThreshold( float scale ) { IlowF = IavgF - (IdiffF * scale); cv::split( IlowF, Ilow ); } void adjustThresholds(char** argv, cv::Mat &img) { int key = 1; while((key = cv::waitKey()) != 27 && key != 'Q' && key != 'q') // Esc or Q or q to exit { if(key == 'L') { low_thresh += 0.2;} if(key == 'l') { low_thresh -= 0.2;} if(key == 'H') { high_thresh += 0.2;} if(key == 'h') { high_thresh -= 0.2;} cout << "H or h, L or l, esq or q to quit; high_thresh = " << high_thresh << ", " << "low_thresh = " << low_thresh << endl; setHighThreshold(high_thresh); setLowThreshold(low_thresh); backgroundDiff(img, mask); showForgroundInRed(argv, img); } } *** MORE TEXT P-456 ..."We perform segmentation by calling:" // Create a binary: 0,255 mask where 255 (red) means foreground pixel // I Input image, 3-channel, 8u // Imask Mask image to be created, 1-channel 8u // void backgroundDiff( cv::Mat& I, cv::Mat& Imask) { I.convertTo( tmp, CV_32F ); // To float cv::split( tmp, Igray ); // Channel 1 // cv::inRange( Igray[0], Ilow[0], Ihi[0], Imask ); // Channel 2 // cv::inRange( Igray[1], Ilow[1], Ihi[1], Imaskt ); Imask = cv::min( Imask, Imaskt ); // Channel 3 // cv::inRange( Igray[2], Ilow[2], Ihi[2], Imaskt ); Imask = cv::min( Imask, Imaskt ); // Finally, invert the results // Imask = 255 - Imask; } *** MORE TEXT P-457 ... "any foreground objects detected are highlighted in red:" *** void help(char** argv ) { cout << "\n" << "Train a background model on the first <#frames to train on> frames of an incoming video, then run the model\n" << argv[0] <<" <#frames to train on> <avi_path/filename>\n" << "For example:\n" << argv[0] << " 50 ../tree.avi\n" << endl; } void showForgroundInRed( char** argv, const cv::Mat &img) { cv::Mat rawImage; cv::split( img, Igray ); Igray[2] = cv::max( mask, Igray[2] ); cv::merge( Igray, rawImage ); cv::imshow( argv[0], rawImage ); } int main( int argc, char** argv) { cv::namedWindow( argv[0], cv::WINDOW_AUTOSIZE ); cv::VideoCapture cap; if((argc < 3)|| !cap.open(argv[2])) { cerr << "Couldn't run the program" << endl; help(argv); cap.open(0); return -1; } int number_to_train_on = atoi( argv[1] ); // FIRST PROCESSING LOOP (TRAINING): // int frame_count = 0; int key; bool first_frame = true; cout << "Total frames to train on = " << number_to_train_on << endl; //db while(1) { cout << "frame#: " << frame_count << endl; cap >> image; if(frame_count == 0) { AllocateImages(image);} if( !image.data ) exit(1); // Something went wrong, abort accumulateBackground( image ); cv::imshow( argv[0], image ); frame_count++; if( (key = cv::waitKey(7)) == 27 || key == 'q' || key == 'Q' || frame_count >= number_to_train_on) break; //Allow early exit on space, esc, q } // We have accumulated our training, now create the models // cout << "Creating the background model" << endl; createModelsfromStats(); cout << "Done! Hit any key to continue into single step. " << " Hit 'a' or 'A' to adjust thresholds, esq, 'q' or 'Q' to quit\n" << endl; // SECOND PROCESSING LOOP (TESTING): // while((key = cv::waitKey()) != 27 || key == 'q' || key == 'Q' ) { // esc, 'q' or 'Q' to exit cap >> image; if( !image.data ) exit(0); cout << frame_count++ << endl; backgroundDiff( image, mask ); // A simple visualization is to write to the red channel // showForgroundInRed( argv, image); if(key == 'a') { cout << "In adjust thresholds, 'H' or 'h' == high thresh up " << "or down; 'L' or 'l' for low thresh up or down." << endl; cout << " esq, 'q' or 'Q' to quit " << endl; adjustThresholds(argv, image); cout << "Done with adjustThreshold, back to frame stepping, " << "esc, q or Q to quit." << endl; } } exit(0); }

Gary Bradski  May 23, 2017  Aug 20, 2021
PDF
Page 464
The first line

The first line should be if( sums.empty ) { instead of if( sum.empty ) {

Note from the Author or Editor:
Reader is correct. * Please change "if( sum.empty )" to "if( sums.empty )" at the top of p465

Anonymous  Jan 31, 2017  Dec 15, 2017
PDF
Page 473
Paragraph before last code snippet

updateCodebook() adds a new codebook... should read updateCodebook() adds a new codeword

Note from the Author or Editor:
Reader is correct. * Please change "codebook if needed" to "codeword if needed" (about 3/4 of the way down p473)

Anonymous  Jan 31, 2017  Dec 15, 2017
PDF
Page 485
Footnote 18

The whole footnote should be deleted because, starting from version 3.0, class cv::BackgroundSubtractor is indeed abstract - all its member functions are pure virtual.

Note from the Author or Editor:
Reader is correct. This is a case in which the evolution of the library got ahead of the book. * Delete footnote 18 completely from the bottom of page 485 (and superscript reference to footnote at the middle of the same page)

Anonymous  Feb 01, 2017  Dec 15, 2017
PDF
Page 492
Paragraph 1

The function name find_connected_components() should be replaced with findConnectedComponents() (see page 478)

Note from the Author or Editor:
Reader is correct. * Please change "find_connected_components()" to "cv::findConnectedComponents()".

Anonymous  Feb 01, 2017  Dec 15, 2017
Printed
Page 509
Example 16-1

There are a few minor errors in the code listing for example 16-1: In the definition of the help() function it currently reads: void help( argv ) { argv needs a type, e.g.: void help( char **argv) { Within the main() function, at the top of page 510 MAX_CORNERS is being redefined. It was previously defined near the very top of the file, following the "using" statement. In the call to calcOpticalFlowPyrLK, the noArray() argument needs the cv:: namespace qualifier. In the call to line() at the top of page 511, the last argument reads CV::AA, but it should be CV::LINE_AA.

Note from the Author or Editor:
Reader is correct, please make the following changes and corrections: * Change "help( argv )" to "help( char** argv )" p509 * Change "noArray()" to "cv::noArray" (about 3/4 of the way down p510) * replace line "const int MAX_CORENERS = 500;" with a blank line (top of p510) * change "cv::imread argv[2]" with "cv::imread( argv[2]" (bottom of p509, note added parenthesis.) * change "AA" to "LINE_AA" (top of p511)

Chris Hennes  Jan 19, 2017  Dec 15, 2017
PDF
Page 525
Last paragraph

Finally, the clone() and create() methods allow you to make a copy of a descriptor or create a new one by name, respectively. should read Finally, the clone() and create() methods allow you to make a copy of a matcher or create a new one by name, respectively.

Note from the Author or Editor:
Reader is correct, please change "of a descriptor or create" to "of a matcher or create" (middle of p525).

Anonymous  Feb 03, 2017  Dec 15, 2017
PDF
Page 536
Paragraph 1

... there are also the all-important detect() routines inherited from the cv::FeatureDetector interface. should read there are also the all-important detect() routines inherited from the cv::Feature2D interface.

Note from the Author or Editor:
Reader is correct. * Please change "the cv::FeatureDetector interface" to "the cv::Feature2D interface" (top of p536).

Anonymous  Feb 04, 2017  Dec 15, 2017
PDF
Page 570
Last paragraph

The sentence Note that by default the locations of the features are not scaled, only the scale value assigned to them. is the other way round. By default the step between features is scaled (bool varyXyStepWithScale = true)

Note from the Author or Editor:
Reader is correct * please delete the sentence "Note that by default the locations of the features are not scaled, only the scale value assigned to them." (bottom of p570). * also change "This will be the spacing between all of the features on all levels, unless varyXyStepWithScale is set to true, in which case the step between the features will also be scaled by one power of featureScaleMul for each level above the first that scale was generated on." to read: "If featureScaleLevels is larger than one, then the locations of the features will, by default, also be scaled by one power of featureScaleMul for each level after the first. If varyXyStepWithScale is set to false, then only the scale value is assigned to the features will change (and not their locations)." (Please also note that in the above text: 'featureScaleLevels', 'featureScaleMul', 'varyXyStepWithScale', and 'false', should all be in "inline code" font.)

Anonymous  Feb 06, 2017  Dec 15, 2017
PDF
Page 581
Footnote 63

No, figures 16-2, 16-4, and 16-9 have nothing to do with drawKeypoints()

Note from the Author or Editor:
Reader is correct. * Please change "Figures 16-2, 16-4, and 16-9" to "Figures 16-11, 16-13, and 16-17".

Anonymous  Feb 07, 2017  Dec 15, 2017
PDF
Page 645
Footnote 11

... in our case the fact that f(r = 0) at r = 0 implies ... should read ... in our case the fact that f(r) = 0 at r = 0 implies ...

Note from the Author or Editor:
Reader is correct * Please change "f(r=0)" to "f(r)=0" in footnote at the bottom of p645.

Anonymous  Feb 11, 2017  Dec 15, 2017
PDF
Page 657
The second to last paragraph

The argument count is an integer equal to the number of corners. There's no such argument. The sentence should be removed.

Note from the Author or Editor:
Reader is correct. * Please remove completely the sentence "The argument count is an integer equal to the number of corners." from the second to last paragraph on p 657

Anonymous  Feb 12, 2017  Dec 15, 2017
PDF
Page 740
First paragraph

Figure 19-14 shows disparity search limits of five pixels... should read Figure 19-15 shows disparity search limits of five pixels... Also, ...from the cameras (see Figure 19-15). should read ...from the cameras (see Figure 19-16). And As shown in Figure 19-14, should read As shown in Figure 19-15,

Note from the Author or Editor:
Reader is correct, and there is one more closely related correction as well. * In the second paragraph on p740, the figures referenced are, in order: "Figure 19-14 shows disparity...", "...cameras (see Figure 19-15).", and "As shown in Figure 19-14". Each of these references is off by one, please replace with: "Figure 19-15 shows disparity...", "...cameras (see Figure 19-16).", and "As shown in Figure 19-15". * Also, in the final paragraph on p740, "illustrated in Figure 19-16" should be changed to read "illustrated in Figure 19-17".

Anonymous  Feb 16, 2017  Dec 15, 2017