《学习OpenCV 3(中文版)》 —不那么简单的变换
不那么简单的变换
接下来,我们要了解如何做更多有意思的事情。在示例2-5中,我们没有任何特殊目的地使用了高斯模糊。现在我们将使用高斯模糊来对一张图像实现基2的降采样[Rosenfeld80]。如果我们对图像进行多次降采样,就要建立一个尺度空间(也称为“图像金字塔”),这一方法是计算机视觉用于处理传感器和目标尺度变化的常用手段之一。
对于那些了解信号处理和香农-奈奎斯特采样理论[Shannon49]的读者,对信号的降采样 (在本例中,我们创建一个图像并对每个像素进行采样)等效于和一系列脉冲函数进行卷积(将这些函数视为“峰值”)。这样的采样会把高频分量引入输出信号(图像)。为了避免这样的事情发生,我们希望首先通过一个高通滤波器来限制信号带宽,使其能够在采样频率之内。在OpenCV中,高斯模糊以及降采样通过cv::pyrDown()函数来实现,我们的实现在示例2-6中。
示例2-6:使用cv::pyrDown()来创建一个新的图像,其宽高均为原始图像的一半
#include <opencv2/opencv.hpp> int main( int argc, char** argv ) { cv::Mat img1,img2;
cv::namedWindow( "Example1", cv::WINDOW_AUTOSIZE ); cv::namedWindow( "Example2", cv::WINDOW_AUTOSIZE );
img = cv::imread( argv[1] ); cv::imshow( "Example1", img1 );
cv::pyrDown( img1, img2); cv::imshow( "Example2", img2 ); cv::waitKey(0); return 0;
};
然后,让我们来分析一段相似但更加复杂的代码,示例2-7这段代码包含有Canny边缘检测器[Canny86]cv::Canny()。在示例2-7中,边缘检测器通过cv::cvtColor()函数生成一个和原图一样大小但只有一个通道的图像,从而将图像从BGR图像转换为灰度图,这个操作在OpenCV中定义为宏cv::COLOR_BGR2GRAY。
示例2-7:Canny边缘检测器输出一个单通道的(灰度)图像
#include <opencv2/opencv.hpp> int main( int argc, char** argv ) {
cv::Mat img_rgb, img_gry, img_cny;
cv::namedWindow( "Example Gray", cv::WINDOW_AUTOSIZE ); cv::namedWindow( "Example Canny", cv::WINDOW_AUTOSIZE ); img_rgb = cv::imread( argv[1] );
cv::cvtColor( img_rgb, img_gry, cv::COLOR_BGR2GRAY); cv::imshow( "Example Gray", img_gry );
cv::Canny( img_gry, img_cny, 10, 100, 3, true ); cv::imshow( "Example Canny", img_cny ); cv::waitKey(0);
}
这时,我们可以将很多简单的操作串联起来。比如说,如果我们想要收缩两次图像然后寻找收缩过两次的图像中的边缘,我们可以像示例2-8一样处理。
示例2-8:在一个简单图像处理流程中结合图像金字塔操作(两次)和Canny边缘检测器 cv::cvtColor( img_rgb, img_gry, cv::BGR2GRAY ); cv::pyrDown( img_gry, img_pyr ); cv::pyrDown( img_pyr, img_pyr2 );
cv::Canny( img_pyr2, img_cny, 10, 100, 3, true ); // do whatever with 'img_cny' //
...
在示例2-9中,我们展示了一个简单的方法来读写示例2-8的像素值。
示例2-9:读写示例2-8中的像素值
int x = 16, y = 32;
cv::Vec3b intensity = img_rgb.at< cv::Vec3b >(y, x);
// ( Note: We could write img_rgb.at< cv::Vec3b >(x,y)[0] )
// uchar blue = intensity[0]; uchar green = intensity[1]; uchar red = intensity[2];
std::cout << "At (x,y) = (" << x << ", " << y << "): (blue, green, red) = (" << (unsigned int)blue <<
", " << (unsigned int)green << ", " << (unsigned int)red << ")" << std::endl;
std::cout << "Gray pixel there is: " <<
(unsigned int)img_gry.at<uchar>(y, x) << std::endl; x /= 4; y /= 4;
std::cout << "Pyramid2 pixel there is: " <<
(unsigned int)img_pyr2.at<uchar>(y, x) << std::endl; img_cny.at<uchar>(x, y) = 128; // Set the Canny pixel there to 128
- 点赞
- 收藏
- 关注作者
评论(0)