图像二值化的OpenCV

图像二值化的OpenCV,第1张

OpenCV中有两个函数可以实现的二值化:
(1)cvThreshold( dst, dst,230 , 255, CV_THRESH_BINARY_INV);
(2)cvAdaptiveThreshold( dst, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY, 9, -10);
方法(1)是手动指定一个阈值,以此阈值来进行二值化处理。其中的第四个参数决定了该方法的结果:
threshold_type=CV_THRESH_BINARY:
dst(x,y) = max_value, if src(x,y)>threshold 0, otherwise
threshold_type=CV_THRESH_BINARY_INV:
dst(x,y) = 0, if src(x,y)>threshold; dst(x,y) = max_value, otherwise
threshold_type=CV_THRESH_TRUNC:
dst(x,y) = threshold, if src(x,y)>threshold; dst(x,y) = src(x,y), otherwise
threshold_type=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold ; dst(x,y) = 0, otherwise
threshold_type=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold ; dst(x,y) = src(x,y), otherwise
值得一说的是threshold_type可以使用CV_THRESH_OTSU类型,这样该函数就会使用大律法OTSU得到的全局自适应阈值来进行二值化,而参数中的threshold不再起 作用。比如:cvThreshold( dst, dst,300 , 255, CV_THRESH_OTSU | CV_THRESH_BINARY_INV);这种方法对于灰度直方图呈现二峰特征的处理起来效果很好。
方法(2)是一个自适应阈值二值化方法,通过设定最后两个参数来调整效果。

看到你这个 首先我感觉你这个偏绿的问题 是因为你错误的把摄像头传回来的YCbCr色彩空间的图像用rgb来显示了,或者就是你rgb弄成了bgr显示,先调整一下图像读取显示的问题 呵呵
另外 就你这个贴出来的,肯定是受到摄像头的限制,有扭曲的问题,找找摄像头标定的代码,先恢复到正常的图像,然后再去想怎么做,处理的素材不好,后面什么算法都是白搭
至于识别的问题,不知道你想识别什么,常见的机器人识别里面识别道路的话最好先弄一点先验知识,呵呵算是一点点经验之谈,如果我没猜错,建议你查查美国国防部的darpa challenge(好像是这么写) 都是机器视觉导航的 可以开开眼界

Mat类:
是用于保存图像以及其他矩阵数据的数据结构。
图像载入函数imread():
Mat imread(const string& filename, int flags=1);
filename表示图像载入的路径;
flags为载入标识。
flags=0 将图像转换为灰度再返回;
flags=1 将图像转换成彩色再返回;
flags=2 若载入图像的深度是16位或者32位,就返回对应的图像深度,否则,将图像转换为8位图像再返回。
flags=2|4 载入最真实无损的源图像
若flags不在枚举类型当中,flags>0 返回一个三通道的彩色图像;flags=0 返回灰度图像;flags<0 返回包含Alpha通道的加载图像。
图像显示函数imshow():
void imshow(const string& winname, InputArray mat);
winname填写要显示的窗口标识名称;
mat填需要显示的图像。
输出图像到文件imwrite():
bool imwrite(const string& filename, InputArray img, const vector& params=vector());
第一个参数filename表示要写入的文件名
第二个参数img表示Mat类型的图像数据
通道分离split()函数;
void split(const Mat& src, Mat mvbegin);
void split(InputArray m, OutputArrayofArray mv);
第一个参数表示需要进行分离的多通道数组;
第二个参数表示函数 输出数组或输出的vector容器。
通道合并merge()函数:
void merge(const Mat mv, size_t count, OutputArray dst)
void merge(InputArrayOfArray mv, OutputArray dst);
第一个参数mv表示需要被合并的输入矩阵或vector容器的阵列,mv参数中所有矩阵必须拥有一样的尺寸;
第二个参数count表示当mv为空白的C数组时,代表输入矩阵的个数,通常可以省略不写;
第三个参数dst表示输出矩阵,和mv拥有一样的尺寸和深度
Python与OpenCV图像简单 *** 作
文章目录
OpenCV安装
1读取
2保存
3截取部分图像
4翻转
5缩放
6转换为灰度图像
7在一个窗口中显示两张
8绘图功能
OpenCV安装
打开命令行输入 pip install opencv-python(前提是有python环境)
1读取
使用 cv2imread() 函数,给出了几种读取路径的写法
import cv2#导入opencv包
#python中不需要声明变量
img1 = cv2imread("D:/test/1jpg")#绝对路径,推荐
img2 = cv2imread("D:\\test\\2jpg")#通常是两个斜线,单右斜线会被当成转义符
img3 = cv2imread("3jpeg")#相对路径,将放在py文件对应目录下
cv2imshow("test1", img1)
cv2imshow("test2", img2)
cv2imshow("test3", img3)
cv2waitKey(0)#没有这一句会一闪而过
##waitkey(delay=0),等待用户输入按键,返回该按键的值
2保存
使用 cv2write() 函数保存
import cv2# 导入OpenCV包
img=cv2imread("D:/test/3png",cv2IMREAD_COLOR)
cv2imshow("test",img)#OpenCV可以实现不同格式转换,支持jpg、bmp、png等格式相互无损转换
cv2imwrite("D:/test/31png",img)#将改变后的图像保存
cv2imwrite("D:/test/32bmp",img)
cv2waitKey(0)
3截取部分图像
import cv2
img = cv2imread("D:\\test\\2jpg")
frame = img[200:400,200:400] #截取部分图像,200-400行,200-400列
cv2imshow("test",frame)#显示截取后的图像
cv2waitKey(0)
4翻转
使用cv2flip(img,flipcode)来进行翻转
flipcode控制翻转方向
import cv2
img=cv2imread("D:/test/5jpg",cv2IMREAD_COLOR)
flipCode1=1#大于0左右翻转
flipCode2=0#等于0上下翻转
flipCode3=-1#小于0先上下翻转再左右翻转
img1 = cv2flip(img, flipCode1)#filpCode控制翻转方向
img2 = cv2flip(img, flipCode2)
img3 = cv2flip(img, flipCode3)
cv2imshow("test",img)
cv2imshow("test1",img1)
cv2imshow("test2",img2)
cv2imshow("test3",img3)
cv2waitKey(0)
5缩放
cv2resize(img,dsize,fx,fy),dsize和fx,fy都可以设置大小,不能同时为0
import cv2# 导入OpenCV包
img = cv2imread("D:/test/2jpg",cv2IMREAD_COLOR)
img1 = cv2resize(img, (700, 700))#设置输出的尺寸
img2 = cv2resize(img, None, fx=07, fy=07)#None的位置本来是输出的尺寸,这里设置了缩放因子
#fx-水平轴上的比例因子,fy-垂直轴上的比例因子
cv2imshow("test", img)
cv2imshow("test1", img1)
cv2imshow("test2", img2)
cv2imwrite("D:/test/resizejpg", img1)# 保存图像
cv2waitKey(0)
6转换为灰度图像
cv2cvtColor(img, cv2COLOR_RGB2GRAY)
cv2COLOR_RGB2GRAY表示把RGB图像转为灰度图像,2前是转换前,2后是转换后
import cv2#导入opencv包
#python中不需要声明变量
img = cv2imread("D:/test/1jpg")#cv2imread读进来的格式是BGR(W,H,C),而不是RGB
cv2imshow("BGR", img)
#将图像转换为RGB格式
img1 = cv2cvtColor(img, cv2COLOR_BGR2RGB)#因为opencv读取是按BGR读的,所以转换为RGB反而不像原图
cv2imshow("RGB",img1)
#将图像转换为灰度图像
img2 = cv2cvtColor(img1, cv2COLOR_RGB2GRAY)
cv2imshow("GRAY",img2)
cv2waitKey(0)
7在一个窗口中显示两张
import cv2
import numpy as np
img = cv2imread("D:/test/resizejpg")
img2 = cv2imread("D:/test/resizejpg")
#imgs = nphstack([img,img2])#在水平方向上平铺
imgs = npvstack([img,img2])#在竖直方向上堆叠
cv2imshow("mutil_pic", imgs)
cv2waitKey(0)
8绘图功能
import cv2
import numpy as np
img = 255npones((350,512,3),npuint8)#unit8:0~255
#ones()为创建一个元素均为一的矩阵
font = cv2FONT_HERSHEY_DUPLEX
#font = cv2FONT_HERSHEY_COMPLEX# 设置字体
#文本 # 对象、文本、 位置、 字体、字体大小、颜色、 字体粗细
cv2putText(img, "happy day", (50,300), font, 08, (25, 25, 25), 2,)#颜色可以自己调整,范围为0-255
#线 #起点 终点 颜色 粗细
cv2line(img, (50,310), (185,310), (0, 0,0),4)
#矩形 #左上顶点 右下顶点
cv2rectangle(img, (80,8), (200,100), (0, 255,0),2)
#圆形 #圆心 半径 颜色 控制是否填充 -1表示填充
cv2circle(img,(60,60),30,(0,0,213),1)
#椭圆 #中心点 长轴 短轴 偏转角度,起始角度,终止角度
cv2ellipse(img,(100,300),(100,50),180,0,360,(20,213,79),1)
cv2imshow("Draw", img)
cv2waitKey(0)
1npvstack([img1,img2]) 当img1和img2矩阵维度相同时才能堆叠
2除了imread,imwrite 函数没有返回值以外,flip,resize,cvtColor,vstack,hstack都有返回一个回来。

如何解读直方图 (转)
 
1 平滑型—曝光正确
图1
正确曝光照片的亮度色调分布应该是比较平均的,表现在直方图上其曲线形状看上起平滑饱满,由左端0位置开始,渐进变化,平滑过渡到右端255这个位置,在各亮度等级上均有像数表现,并且在左端(最暗处)和右端(最亮处)没有溢出现象,保留着各亮度的细节层次。
如图1所示,图1的直方图中没有断档和溢出,说明这是一幅曝光准确的照片,亮部和暗部都保留了丰富的层次和细节。

图2
而图2虽然过渡并不平滑,但亮度和暗部均没有溢出,中间也没有断档,所以也是一幅曝光准确的照片。
2 右坡型—曝光不足
曝光不足照片的直方图曲线波形偏重于左侧,多数的像素集中在左侧,波形图的右侧有较明显的下降,并且其右侧到255(最亮处)位置处有一段空白,很少甚至没有像素。这种照片看上去过于暗淡,暗的部位较多,亮调不足,可通过增加曝光补偿、增大光圈或降低快门速度来调整。在用Photoshop进行后期处理时,可以点击“图像→调整→暗调/高光”,拖动“暗调”项滑杆来修正曝光不足。
图3
如图3所示,直方图左边暗部看不见末端,且峰值有溢出现象,表明该幅照片的暗部细节没有被数码相机完全记录下来,溢出部分在照片里表现为“死黑”,这些像素的记录值为0,而右边亮部的峰值很低,且所占比例很小,说明这幅照片曝光不足,画面偏暗,需要增加曝光。
3 左坡型—曝光过度
过曝照片的直方图与曝光不足照片的直方图刚好相反,像素集中于右侧,而左侧的像素很少,从0(最暗处)到曲线波形的起始处有一段空白,很少甚至没有像素,照片的色调很亮,或有大面积的反光源。拍摄时可通过减少曝光补偿、缩小光圈或提高快门速度来调整曝光设置。在用Photoshop进行后期处理时,可以点击“图像→调整→暗调/高光”,拖动“高光”项滑杆来修正过曝现象。
图4
以图4为例,右边亮部的曲线溢出,溢出的部分在照片里表现为“死白”,左边曲线很低,说明画面亮部曝光过度,亮部细节有明显损失。
4 中凸型—反差过低
直方图上的像素集中在曲线的中间部位,波形在中间凸起,两边下降,靠近0和255位置没有像素,缺少暗调和亮调,对比度不足,照片看上去模糊、灰蒙蒙。这种直方图很常见,主要时拍摄时天气等环境因素影响造成,比如有雾、沙尘、太阳光太强等,可使用偏震镜等设备加于调节。在用Photoshop进行后期处理时,可以点击“图像→调整→色阶”,将两端黑白场滑杆分别移动到直方图两侧起始点稍稍向里一点的位置,可使照片的影调得到一定的调整
图5
图5的直方图的峰值集中在中间,左边暗部和右边亮部都缺失,说明反差过低,在阴雨天或者光线不足的条件下拍摄很容易出现反差过低的情况,这张照片就是在阴天拍摄的。
5 中凹型—反差过大
这种照片的直方图曲线波形是两边高、中间凹陷,像素主要集中在左右两侧,中间很少,照片有明显的暗调和亮调部分,但中间中等亮度部分比较缺少,明暗反差大。这种直方图除了特意进行剪影或高反差创作外,主要是没有掌握好测光部位及测光方式,可以将测光点定位在明暗交接部位等方法进行调节。在用Photoshop进行后期处理时,可以点击“图像→调整→暗调/高光”,分别拖动“暗调”和“高光”项的滑杆来修正。
图6
从图6的直方图可以看出,两侧峰值都有溢出,说明画面反差过大,亮度和暗部细节都有所损失,拍摄时最好用中灰减光镜减小反差,或者根据需要以亮部或者暗部为基准曝光,以此图为例,刻意突出松树的质感,而忽略云层的细节。尽管直方图上看上去反差过大,但仍达到了笔者想要的结果。
以上5种形状的直方图是比较典型的直方图,但这并不说明所有照片的直方图都如此,不同照片具有不同形状的直方图,并不是千篇一律的,甚至有些不规则直方图的照片反而正是拍摄者所追求的效果,有些特殊情况,如有些深色背景的照片其直方图也像曝光不足照片一样,曲线偏重于左侧,但曝光是准确的。
所以,用直方图指导曝光时要根据自己的拍摄需要和想要达到的拍摄效果,完全曝光准确的照片未必是效果最好的照片。
另外,为了降低后期处理的难度,拍摄时也不能过去偏离自己的曝光要求。拍摄时最好掌握以下两大曝光原则:
首先,当拍摄场景的动态范围超过数码相机的动态范围时,至少要保证直方图亮部或暗部其中一项不溢出,这时最好的办法是用中灰减光镜降低反差,或者也可以根据你的拍摄需要以亮部或暗部为曝光基准,另外也可以将相机架在三脚架上用包围曝光拍摄几张照片,再在后期用Photoshop等图像处理软件叠加,以扩展照片的动态范围。
其次,“白加黑减”这一曝光法则不仅适用于传统相机,数码相机也同样适用。在画面中亮度或暗部占据很大面积时,要适当增加或减少曝光,至于增加或减少多少曝光量,则根据拍摄场景中所占的比例而定。
总结
用直方图指导曝光是很实用的方法,当然这要建立在你的拍摄主题之上。要准确应用好直方图来判断曝光准确性,还需要多拍、多实践。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13384480.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存