CS 376b Computer Vision 09 / 25 / 2014 Instructor: Michael Eckmann
Today s Topics Questions? / Comments? Enhancing images / masks Cross correlation Convolution C++
Cross-correlation Cross-correlation involves aligning the origin of the mask with a pixel in question and multiplying the corresponding mask pixel values with the pixels in the original image and summing them all up. This summed up value is the value of the new pixel. No divide takes place. Typical masks though will either sum up to 0 or 1. A smoothing mask will sum up to 1. A derivative mask will sum up to 0. Concern: The result of the sum of the multiplications is not guaranteed to be within the range 0.. 255 College - CS 376 - Fall 2014
Derivative and Smoothing masks Derivative masks values have opposite signs in order to obtain a high response in signal regions of high contrast sum of values is 0, so a 0 results from constant regions first derivative masks produce high abs values at points of high contrast second derivative masks produce zero-crossings at points of high contrast Smoothing masks values are positive and sum to 1, so resulting value is same as input in constant regions College - CS 376 - Fall 2014
Convolution Convolution is similar to cross-correlation except the upper-left value in the mask is multiplied by the lower-right value in the image neighborhood and so on until the lower-right value in the mask is multiplied by the upper-left value in the image. think of the mask being flipped along the horizontal axis and then again along the vertical axis AND THEN doing cross-correlation with the flipped mask picture on the board If the mask is symmetrical both vertically and horizontally, then crosscorrelation and convolution yield the same result. The two terms are often confused and sometimes used interchangeably (incorrectly.) College - CS 376 - Fall 2014
Considerations resulting value of output image pixels can be much larger than the input image pixels due to the summation, it is also possible for the output image pixels to yield negative values if the mask contains negatives --- so the type of the new image needs to be considered as possibly being different than the input image type College - CS 376 - Fall 2014
Computational considerations consider the computation involved in convolution or cross-correlation if mask is size n x n, then for each pixel in the input image, we do n 2 multiplies and n 2-1 additions. if a mask is separable into two vectors that, when we take the outer product of them (example on the board), we get the original mask then we can reduce the computational complexity by first convolving or correlating the image with the column vector and then the resulting image can be convolved or correlated with the row vector to get the output image (which would result in the same image as convolving or correlating the nxn mask with the original image). how many multiplies and additions now? College - CS 376 - Fall 2014
Computational considerations if a mask is separable into two vectors that, when we take the outer product of them, we get the original mask then we can reduce the computational complexity by first convolving or correlating the image with the column vector and then the resulting image can be convolved or correlated with the row vector to get the output image (which would result in the same image as convolving or correlating the nxn mask with the original image). how many multiplies and additions now? (2n multiplies and 2(n-1) additions) per pixel College - CS 376 - Fall 2014
Smoothing examples College - CS 376 - Fall 2014
Smoothing examples College - CS 376 - Fall 2014
Smoothing examples College - CS 376 - Fall 2014
Estimating the gradient Often we want to find boundaries in images and know how sharp the boundaries are and in which direction the boundaries are. Given f(x,y) as our image function, we would like to compute the gradient at pixels [x,y]. The magnitude of the gradient will give us an indication of how sharp a boundary is, and the angle of the gradient will give us the direction. If we want to estimate the magnitude and direction of the gradient (where the maximum change occurs) do the following: the partial derivative of f w.r.t. x and the partial derivative of f w.r.t y make up the gradient. College - CS 376 - Fall 2014
Estimating the gradient The partial derivative of f w.r.t. x (f x ) and the partial derivative of f w.r.t y (f y ) make up the gradient. We can estimate these values in a discrete image at pixel x,y: for f x : take the difference between the pixel at x-1, y and x+1, y and divide by the change in x (2 pixels) for f y : take the difference between the pixel at x, y-1 and x, y+1 and divide by the change in y (2 pixels) We can get a better estimate if we average these calculations above and below and to the right and left of the pixel in question. Example on the board (figure 5.14) (draw triangle) The magnitude of the gradient is the square root of the sum of the squares of the partials The direction of the gradient is the angle which is arctan(f y / f x ) College - CS 376 - Fall 2014
Estimating the gradient These lead to the Prewitt masks The Sobel masks come from the same idea but with twice the weight given to the row/col the pixel is in. These masks are shown in figure 5.15 let me write them on the board and discuss College - CS 376 - Fall 2014
Now C++ College - CS 376 - Fall 2014
C++ C++ Bjarne Stroustrup (designer and 1 st implementer) designed to be fast object oriented C is almost a proper subset of C++ that is, a valid C program should typically be a valid C++ program
C++ vs. Java In C++ but not in Java can use pointers to memory locations have a pointer to a reference to an object that has been returned to the heap (destroyed) dangling pointer problem explicit programmer deallocation of memory allowed memory leaks no garbage collection array indices are not checked unpredictable behaviour when accessing array elements beyond end of array
C++ vs. Java In C++ but not in Java allow use of uninitialized variables (causes runtime error) allowed to not return a value from a non-void function can overload operators e.g. for a class I can overload the + operator to perform some operation on objects of that class. more flexible than requiring a function. can have global functions that are not part of any class
C++ vs. Java In C++ but not in Java has a preprocessor which can be used for (among other things) conditional compilation has the STL which contains things similar to what is found in Java Collections API has templates whereas Java uses generics for same purpose
C++ vs. Java c++ has fewer compile time checks (which generate errors) than Java c++ has fewer run time checks c++ has no standard GUI library c++ has fewer standard library functions vs. the large Java API c++ is not as portable as Java, but there are guidelines out there to which one should try to adhere for more portable c++
C++ from C There are programming features leftover from C that can be used in c++. c-style strings, c-style dynamic memory management, c-style printing, etc. we will look at the c-style way of doing things, but typically prefer the c++ way. we need to know the C ways because they are part of valid c++ programs and we need to be able to read code not written by us that may use the C style stuff and sometimes we might want to call a C function in some C library...
Some types C++ int, short, long float, double, long double any of the above numeric types can be prefaced with signed or unsigned char (typically 8 bits) wchar_t (wide = larger than a char) bool (0 = false, 1 = true) ints can be interpreted as bool (holdover from C which had no bool), 0=false, any other int is true. void enum (creates an integer type and named constants)
Some types C++ union union number { int x; double y; long double z; }; number num;
C++ // Hello.cpp #include <iostream> using namespace std; int main() { cout << "Hello, world!" << endl; return 0; }
C++ // #include logically inserts the code from the iostream file into this file // (Hello.cpp) // iostream is a system header file so we use the < > // if we wanted to include our own user-defined header file then we use " " // int main() is the function declaration (all programs need one main) // can take 2 arguments if defined with them (int argc, char **argv) // returns an int // cout is like System.out.println // << is an operator for writing // >> is an operator for reading // endl is a newline character
C++ // note: cout and endl are in the std namespace (like a package in java) // without using namespace std, we could: // std::cout << "Hello, world!" << std::endl;
C++ The C++ specification does not specify the exact sizes of the types therefore they are implementation dependent. If you want to know the size of a type on a particular system, you can use the sizeof operator in C++ to get this info. Let's see a program that uses this sizeof operator and prints the sizes of the various types. We write/edit/compile/run C++ programs with Eclipse, or we can use the command line like: g++ mycode.cpp -o mycode.o then to execute your program do:./mycode.o
C++ Like Java, C++ has for, while and do-while loops, C++ has if's and else's C++ has switch statements with cases C++ has same arithmetic operators C++ has same relational operators
C++ >> and << when used on ints do a shift. int x = 10; x = x << 2; // shift left by 2 bits multiplies by 4 cout << x << endl; // will be 40 >> is a shift right (divides by 2 * right operand) padding high bits with 0's?
More types C++ array similar to Java int nums[30]; // array of 30 ints, index starts at 0 int ages[] = {21, 18, 35, 52, 65}; can't put brackets before the name (but in Java can)
More types C++ objects a simple declaration in Java creates a reference to a class Card a; // a is a Card reference a simple declaration in C++ creates an object of that class by calling the default constructor string a; // actually calls string's default constructor string s1( Hello ); // calls a different constructor string s2 = string( Bye ); // also calls a constructor s1 = s2; // actually makes a COPY
More types C++ objects string s1( Hello ); // calls a different constructor string s2 = string( Bye ); // also calls a constructor s1 = s2; // actually makes a COPY s2 = So long ; // doesn't affect s1
More types C++ objects/references In Java we can have: Card a; // a reference to a Card (does NOT call Card's default constructor) Card b = new Card(2, 2); a = b; // a and b now both refer to the same object b.setrank(5); // the ONE object has rank 5 and both a and b refer to it This is the typical behaviour in Java (except for Strings where = actually makes a copy of the data not an alias.)
More types C++ objects/references In C++ we can have: Card &a; // a reference to Card (does NOT call Card's default constructor) Card b = new Card(2, 2); a = b; // a and b now both refer to the same object b.setrank(5); // the ONE object has rank 5 and both a and b refer to it see example programs
C++ a struct is a record in C++ and in C e.g. struct PhoneNumber { } int areacode; // first 3 digits, e.g. 518 int exchange; // next 3 digits e.g. 580 int last4; // last 4 digits e.g. 5294 if you know structs from C, they are different in C++. In C++ they are essentially the same as classes except that by default a struct's members are public and by default a class's members are private.
classes in C++ C++ can have multiple inheritance typically divided into header and implementation (usually in different files) class definitions end with a semicolon divided into sections public: private: protected: inline functions - code in the definition header (interface) file vs. implementation file prototypes of functions and classes must appear before use extern destructors should have a default constructor and a copy constructor