How it works...
In order to access the neighboring pixels of the previous and next rows, you must simply define additional pointers that are jointly incremented. You then access the pixels of these lines inside the scanning loop.
In the computation of the output pixel value, the cv::saturate_cast template function is called on the result of the operation. This is because it often happens that a mathematical expression applied on pixels leads to a result that goes outside the range of the permitted pixel values (that is, below 0 or over 255). The solution is then to bring back the values inside this 8-bit range. This is done by changing negative values to 0 and values over 255 to 255. This is exactly what the cv::saturate_cast<uchar> function is doing. In addition, if the input argument is a floating-point number, then the result is rounded to the nearest integer. You can obviously use this function with other types in order to guarantee that the result will remain within the limits defined by this type.
Border pixels that cannot be processed because their neighborhood is not completely defined need to be handled separately. Here, we simply set them to 0. In other cases, it could be possible to perform a special computation for these pixels, but most of the time, there is no point in spending the time to process these very few pixels. In our function, these border pixels are set to 0 using two special methods. The first one is row and its dual is col. They return a special cv::Mat instance composed of a single-line ROI (or a single-column ROI) as specified in a parameter (remember, we discussed regions of interest in the previous chapter). No copy is made here because if the elements of this one-dimensional matrix are modified, they will also be modified in the original image. This is what we do when the setTo method is called. This method assigns a value to all the elements of a matrix. Take a look at the following statement:
result.row(0).setTo(cv::Scalar(0));
The preceding statement assigns the value of 0 to all pixels of the first line of the resulting image. In the case of a three-channel color image, you would use cv::Scalar(a,b,c) to specify the three values to be assigned to each channel of the pixel.