Learning OpenCV3-阈值化

完成许多处理步骤之后,通常希望对图像中的像素做出最后的决策,或直接剔除一些低于或高于一定值的像素。在OpenCV中,函数cv::threshold()可以完成这些任务。其基本思想是,给定一个数组和一个阈值,然后根据数组中的每个元素的值是低于还是高于阈值而进行一些处理。

double cv::threshold(
    cv::InputArray  src,            // Input image
    cv::OutputArray dst,            // Result image
    double          thresh,         // Threshold value
    double          maxValue,       // Max value for upward operations
    int             thresholdType   // Threshold type to use
);

如下图所示,每个与之类型对应于一个特定的比较操作,该比较操作在源图像第 i 个像素( src i )和阈值之间进行。根据源图像的像素和阈值之间的关系,目标图像的像素dst i可能被设置为0, src i 或者最大值maxValue。

cv::threshold()中阈值类型选项和对应的操作
这里写图片描述
下图有助于我们理解每一个阈值类型的确切操作
这里写图片描述
我们来看一个简单例子。我们对图像中的三个通道就和,然后在值为100处,对结果图像进行截断。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
void sum_rgb( const cv::Mat& src, cv::Mat& dst ) {
    // Split image onto the color planes.
    //
    vector< cv::Mat> planes;
    cv::split(src, planes);
    cv::Mat b = planes[0], g = planes[1], r = planes[2], s;
    // Add equally weighted rgb values.
    //
    cv::addWeighted( r, 1./3., g, 1./3., 0.0, s );
    cv::addWeighted( s, 1., b, 1./3., 0.0, s );
    // Truncate values above 100.
    //
    cv::threshold( s, dst, 100, 100, cv::THRESH_TRUNC );
}
void help() {
    cout << "Call: ./ch10_ex10_1 faceScene.jpg" << endl;
    cout << "Shows use of alpha blending (addWeighted) and threshold" << endl;
}
int main(int argc, char** argv) {
    help();
    if(argc < 2) { cout << "specify input image" << endl; return -1; }
    // Load the image from the given file name.
    //
    cv::Mat src = cv::imread( argv[1] ), dst;
    if( src.empty() ) { cout << "can not load " << argv[1] << endl; return -1; }
    sum_rgb( src, dst);
    // Create a named window with the name of the file and
    // show the image in the window
    //
    cv::imshow( argv[1], dst );
    // Idle until the user hits any key.
    //
    cv::waitKey(0);
    return 0;
}

这里包含几个重要的思想。第一,我们通常不会对8位数组进行加法运算,因为较高的位可能会溢出。取而代之,我们使用加权加法算法(cv::addWeighted())对三个通道求和;然后对结果以100为阈值进行截断处理然后返回。我们在例子中使用了s的浮点临时图像。我们可以用下一个例子中所示的代码代替。请注意,cv :: accumulate()可以将8位整数图像类型累加到浮点图像中。

void sum_rgb( const cv::Mat& src, cv::Mat& dst ) {
    // Split image onto the color planes.
    //
    vector<cv::Mat> planes;
    cv::split(src, planes);
    cv::Mat b = planes[0], g = planes[1], r = planes[2];
    // Accumulate separate planes, combine and threshold.
    //
    cv::Mat s = cv::Mat::zeros(b.size(), CV_32F);
    cv::accumulate(b, s);
    cv::accumulate(g, s);
    cv::accumulate(r, s);
    // Truncate values above 100 and rescale into dst.
    //
    cv::threshold( s, s, 100, 100, cv::THRESH_TRUNC );
    s.convertTo(dst, b.type());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值