Errata
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: |
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 |
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 |
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 |
Feb 18, 2017 | Dec 15, 2017 |
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: |
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: |
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 |
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: |
Eric Lovejoy | Jan 19, 2017 | Dec 15, 2017 |
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: |
João Ferreira Nunes | Jan 26, 2017 | Dec 15, 2017 | |
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 | |
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 | |
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: |
Anonymous | Jan 24, 2017 | Dec 15, 2017 | |
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: |
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: |
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: |
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 |
Feb 19, 2017 | Dec 15, 2017 |
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 | |
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 | |
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 | |
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 |
Jul 06, 2017 | Aug 20, 2021 |
Page 106 cv::normalize() |
The description refers to the argument dtype as rtype in two places |
Philipp Deibert | Sep 25, 2016 | Dec 09, 2016 | |
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 | |
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 | |
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 | |
Page 120 Footnote 2 |
Footnote 2 refers to cv::fillComvexPolyfillConvexPoly(). Probably fillConvexPoly() was meant instead. |
Philipp Deibert | Sep 28, 2016 | Dec 09, 2016 | |
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 | |
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 | |
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 | |
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 | |
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: |
Dave Burke | Jan 24, 2017 | Dec 15, 2017 | |
Page 189 footnote #4 |
reported ' vector<int>&' should be ' vector<uchar>&" Note from the Author or Editor: |
Anonymous | Jan 27, 2017 | Dec 15, 2017 | |
Page 198 3rd paragraph |
FileStorage::FileStorage(); should be cv::FileStorage::FileStorage(); It's more clear. Note from the Author or Editor: |
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: |
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: |
Seunghoon Jung | Feb 12, 2017 | Dec 15, 2017 |
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: |
Anonymous | Jan 30, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 06, 2017 | Dec 15, 2017 | |
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 |
Mar 03, 2017 | Aug 20, 2021 |
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: |
Kouichi MATSUDA | Feb 08, 2017 | Dec 15, 2017 | |
Page 273 definition of cv::Laplacian function |
4th argument type is 'int' (not cv::Size) Note from the Author or Editor: |
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 |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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 | |
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 | |
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: |
Anonymous | Jan 29, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Jan 17, 2017 | Jan 20, 2017 | |
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: |
Anonymous | Feb 10, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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: |
Kouichi MATSUDA | Feb 18, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Jan 29, 2017 | Dec 15, 2017 | |
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: |
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 |
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: |
Anonymous | Jan 30, 2017 | Dec 15, 2017 | |
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 | |
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: |
Anonymous | Jan 30, 2017 | Dec 15, 2017 | |
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 | |
Page 464 The first line |
The first line should be if( sums.empty ) { instead of if( sum.empty ) { Note from the Author or Editor: |
Anonymous | Jan 31, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Jan 31, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 01, 2017 | Dec 15, 2017 | |
Page 492 Paragraph 1 |
The function name find_connected_components() should be replaced with findConnectedComponents() (see page 478) Note from the Author or Editor: |
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: |
Chris Hennes | Jan 19, 2017 | Dec 15, 2017 |
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: |
Anonymous | Feb 03, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 04, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 06, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 07, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 11, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 12, 2017 | Dec 15, 2017 | |
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: |
Anonymous | Feb 16, 2017 | Dec 15, 2017 |