我们常常需要对图像中的像素做出取舍与决策,直接剔除一些低于或者高于一定值的像素(例如只想要图中红色的东西,这就派上用场了)
Threshold函数
- THRESH_BINARY(二进制阈值:二值阈值化(某范围保留,其余为0黑色))二值中的maxval很重要,根据thresh和maxval就相当于取范围了
d s t ( x , y ) = { m a x v a l , i f s r c ( x , y ) > t h r e s h 0 , o t h e r w i s e s dst(x,y)=\begin{cases} maxval, & if \ src(x,y)>thresh \\ 0, & otherwises \end{cases} dst(x,y)={maxval,0,if src(x,y)>threshotherwises
- THRESH_BINARY_INV(反二进制阈值)
d s t ( x , y ) = { 0 , i f s r c ( x , y ) > t h r e s h m a x v a l , o t h e r w i s e s dst(x,y)=\begin{cases} 0, & if \ src(x,y)>thresh \\ maxval, & otherwises \\ \end{cases} dst(x,y)={0,maxval,if src(x,y)>threshotherwises - THRESH_TRUNC(截断阈值:截断阈值)
d s t ( x , y ) = { t h r e s h o l d , i f s r c ( x , y ) > t h r e s h s r c ( x , y ) , o t h e r w i s e s dst(x,y)=\begin{cases} threshold, & if \ src(x,y)>thresh \\ src(x,y), & otherwises \\ \end{cases} dst(x,y)={threshold,src(x,y),if src(x,y)>threshotherwises
- THRESH_TOZERO(反阈值化为0:超过阈值为0)
d s t ( x , y ) = { s r c ( x , y ) , i f s r c ( x , y ) > t h r e s h 0 , o t h e r w i s e s dst(x,y)=\begin{cases} src(x,y) , & if \ src(x,y)>thresh \\ 0, & otherwises \\ \end{cases} dst(x,y)={src(x,y),0,if src(x,y)>threshotherwises - THRESH_TOZERO_INV(阈值化为0:低于阈值为0)
d s t ( x , y ) = { 0 , i f s r c ( x , y ) > t h r e s h s r c ( x , y ) , o t h e r w i s e s dst(x,y)=\begin{cases} 0 , & if \ src(x,y)>thresh \\ src(x,y), & otherwises \\ \end{cases} dst(x,y)={0,src(x,y),if src(x,y)>threshotherwises
adaptiveThreshold函数
补充知识点:hsv通道
这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
其中H:(360度)
从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;
c++版本
- hsv通道分离
代码:
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <math.h>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
//加载图像
Mat srcImage=imread("/home/liuxin/桌面/opencv/buff.png");
imshow("原始图",srcImage);
//变换成hsv通道
Mat hsvImage;
cvtColor(srcImage,hsvImage,COLOR_BGR2HSV);
//分割split 与合并merge
vector<Mat> hsvsplit;//hsv的分离通道
split(hsvImage,hsvsplit);
imshow("明度",hsvsplit[0]);// v 明度
imshow("饱和度",hsvsplit[1]);// s 饱和度
imshow("色调",hsvsplit[2]);// h 色调
while(1)
{
int key=cvWaitKey(10);
if (key==27)
{
break;
}
}
return(0);
}
- 二值化(阈值化)
注意该结果只是提取了蓝色的因素,因此5号边缘还残留的也保存下来,解决办法是在明度v上也设定范围,这样不够亮的就被去除掉了
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <math.h>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
//加载图像
Mat srcImage=imread("/home/liuxin/桌面/opencv/buff.png");
imshow("原始图",srcImage);
//变换成hsv通道
Mat hsvImage;
cvtColor(srcImage,hsvImage,COLOR_BGR2HSV);
imshow("未增强色调的hsv图片",hsvImage);
//分割split 与合并merge
vector<Mat> hsvsplit;//hsv的分离通道
split(hsvImage,hsvsplit);
equalizeHist(hsvsplit[2],hsvsplit[2]);//直方图均衡化,增强对比度,hsvsplit[2]为返回的h
merge(hsvsplit,hsvImage);//在色调调节后,重新合并
imshow("增强色调对比度后的hsv图片",hsvImage);
Mat thresHold;
threshold(hsvsplit[2],thresHold,240,245,THRESH_BINARY);
imshow("二值化后图片",thresHold);
while(1)
{
int key=cvWaitKey(10);
if (key==27)
{
break;
}
}
return(0);
}