赞
踩
self.sub = rospy.Subscriber("/camera/rgb/image_raw", Image, self.image_cb, queue_size=1)
cv_image = bridge.imgmsg_to_cv2(image_message, desired_encoding="passthrough")
cv_image1 = CvBridge().imgmsg_to_cv2(data, "bgr8")
data:图像名
bgr8:BGR8格式
另外还有Opencv类型到ROS Image类型的转换:
image_message = cv2_to_imgmsg(cv_image, encoding="passthrough")
not_img=cv2.bitwise_not(img1)
cvtcolor()函数是一个颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间转换。也可以转换为灰度图。
cvtColor(Mat src, Mat dst, int code)
src 表示来源的矩阵。 dst 表示目的地的矩阵。 code 表示转换类型的整数代码,例如RGB到灰度。
- pic_hsv = cv2.cvtColor(pic0, cv2.COLOR_BGR2HSV)
- cv2.imshow("hsv_pic",pic_hsv)
额外知识:
cv::cvtColor()支持多种颜色空间之间的转换,其支持的转换类型和转换码如下:
1、RGB和BGR(opencv默认的彩色图像的颜色空间是BGR)颜色空间的转换
cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_RGBA2BGRA
cv::COLOR_BGRA2RGBA2、向RGB和BGR图像中增添alpha通道
cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA3、从RGB和BGR图像中去除alpha通道
cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR4、从RBG和BGR颜色空间转换到灰度空间
cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAYcv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY5、从灰度空间转换到RGB和BGR颜色空间
cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGRcv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA6、RGB和BGR颜色空间与BGR565颜色空间之间的转换
cv::COLOR_RGB2BGR565
cv::COLOR_BGR2BGR565
cv::COLOR_BGR5652RGB
cv::COLOR_BGR5652BGR
cv::COLOR_RGBA2BGR565
cv::COLOR_BGRA2BGR565
cv::COLOR_BGR5652RGBA
cv::COLOR_BGR5652BGRA7、灰度空间域BGR565之间的转换
cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY8、RGB和BGR颜色空间与CIE XYZ之间的转换
cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR9、RGB和BGR颜色空间与uma色度(YCrCb空间)之间的转换
cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR10、RGB和BGR颜色空间与HSV颜色空间之间的相互转换
cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR11、RGB和BGR颜色空间与HLS颜色空间之间的相互转换
cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR12、RGB和BGR颜色空间与CIE Lab颜色空间之间的相互转换
cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGBcv::COLOR_Lab2BGR
13、RGB和BGR颜色空间与CIE Luv颜色空间之间的相互转换
cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR14、Bayer格式(raw data)向RGB或BGR颜色空间的转换
cv::COLOR_BayerBG2RGB
cv::COLOR_BayerGB2RGB
cv::COLOR_BayerRG2RGB
cv::COLOR_BayerGR2RGB
cv::COLOR_BayerBG2BGR
cv::COLOR_BayerGB2BGR
cv::COLOR_BayerRG2BGR
cv::COLOR_BayerGR2BGR
————————————————
感谢:https://blog.csdn.net/weixin_51105360/article/details/113941015
此处再补充一下关于hsv的定义:
其中:
Hue:(色调、色相)
Saturation(饱和度、色彩纯净度)
Value(明度)
圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。
np.array函数的作用:列表不存在维度问题,但数组是有维度的,而np.array()的作用就是把列表转化为数组,也可以说是用来产生数组。
- LowerBlue = np.array([95, 90, 80])
- UpperBlue = np.array([130, 255, 255])
此处设置两个数组来确定蓝色的阈值
一般对颜色空间的图像进行有效处理都是在HSV空间进行的,然后对于基本色中对应的HSV分量需要给定一个严格的范围,下面是通过实验计算的模糊范围(准确的范围在网上都没有给出)。
H: 0 — 180
S: 0 — 255
V: 0 — 255
此处把部分红色归为紫色范围:
- mask = cv2.inRange(pic_hsv, LowerBlue, UpperBlue)
- cv2.imshow("black&white",mask)
cv_image2:原图或者指要进行处理的图
LowerBlue:由上面确定下来的阈值处理,低于这个值的将变为0,即黑色
UpperBlue:同样是由上面确定的阈值,高于这个值将转变成0,即黑色
在LowerBlue~UpperBlue之间的值将转变成255,即白色
因为我采用的是检测蓝色,所以处理结束后图形中蓝色部分将变为白色,其他部分变为黑色,形成黑白二值图,mask就是处理后的图
dst=cv2.bitwise_and(src1,src2[,mask]])
实现按位与运算
- dst表示与输入值具有同样大小的array输出值。
- src1表示第一个array或scalar类型的输入值。
- src2表示第二个array或scalar类型的输入值。
- mask表示可选操作掩码,8位单通道array。
特点:
- 将任何数值N与数值0进行按位与操作,都会得到数值0。
- 将任何数值N(这里仅考虑8位值)与数值255(8位二进制数是1111 1111)进行按位与操作,都会得到数值N本身。
根据上述特点,可以构造一幅掩模图像M,掩模图像M中只有两种值:一种是数值0,另外一种是数值255。将该掩模图像M与一幅灰度图像G进行按位与操作,在得到的结果图像R中:
- 与掩模图像M中的数值255对应位置上的值,来源于灰度图像G。
- 与掩模图像M中的数值0对应位置上的值为零(黑色)。
感谢:https://blog.csdn.net/weixin_45335726/article/details/122415833
- pic_and = cv2.bitwise_and(pic_hsv, pic_hsv, mask=mask)
- cv2.imshow("and_pic",pic_and)
cv_image2:获取到的原hsv图
mask:进行阈值化处理后的二值图
最后得到的图形应该是蓝色方块仍为原色,其他二值化后的部分会变成黑色
了解取反运算
取反运算非常简单,就是黑的变白,白的变黑;当然这样说不严谨,但是却很好反应了取反这个操作的结果;例如0取反则是1,1取反则是0。取反使用bitwise_not方法,bitwise_not方法接收一个图片参数。以下方法依旧使用名为1bit的图片。
not_img = cv2.bitwise_not(img1)
效果:
Python中Array对象的操作:
对于X[:,0]:是取二维数组中第一维的所有数据
对于X[:,1]:是取二维数组中第二维的所有数据
对于X[:,m:n]:是取二维数组中第m维到第n-1维的所有数据
对于X[:,:,0]:是取三维矩阵中第一维的所有数据
对于X[:,:,1]: 是取三维矩阵中第二维的所有数据
对于X[:,:,m:n]: 是取三维矩阵中第m维到第n-1维的所有数据
#!usr/bin/env python #encoding:utf-8 from __future__ import division ''' __Author__:沂水寒城 学习Python中的X[:,0]、X[:,1]、X[:,:,0]、X[:,:,1]、X[:,m:n]和X[:,:,m:n] ''' import numpy as np def simple_test(): ''' 简单的小实验 ''' data_list=[[1,2,3],[1,2,1],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[6,7,9],[0,4,7],[4,6,0],[2,9,1],[5,8,7],[9,7,8],[3,7,9]] # data_list.toarray() data_list=np.array(data_list) print 'X[:,0]结果输出为:' print data_list[:,0] print 'X[:,1]结果输出为:' print data_list[:,1] print 'X[:,m:n]结果输出为:' print data_list[:,0:1] data_list=[[[1,2],[1,0],[3,4],[7,9],[4,0]],[[1,4],[1,5],[3,6],[8,9],[5,0]],[[8,2],[1,8],[3,5],[7,3],[4,6]], [[1,1],[1,2],[3,5],[7,6],[7,8]],[[9,2],[1,3],[3,5],[7,67],[4,4]],[[8,2],[1,9],[3,43],[7,3],[43,0]], [[1,22],[1,2],[3,42],[7,29],[4,20]],[[1,5],[1,20],[3,24],[17,9],[4,10]],[[11,2],[1,110],[3,14],[7,4],[4,2]]] data_list=np.array(data_list) print 'X[:,:,0]结果输出为:' print data_list[:,:,0] print 'X[:,:,1]结果输出为:' print data_list[:,:,1] print 'X[:,:,m:n]结果输出为:' print data_list[:,:,0:1] if __name__ == '__main__': simple_test()X[:,0]结果输出为:
[1 1 3 4 5 6 6 0 4 2 5 9 3]
X[:,1]结果输出为:
[2 2 4 5 6 7 7 4 6 9 8 7 7]
X[:,m:n]结果输出为:
[[1]
[1]
[3]
[4]
[5]
[6]
[6]
[0]
[4]
[2]
[5]
[9]
[3]]
X[:,:,0]结果输出为:
[[ 1 1 3 7 4]
[ 1 1 3 8 5]
[ 8 1 3 7 4]
[ 1 1 3 7 7]
[ 9 1 3 7 4]
[ 8 1 3 7 43]
[ 1 1 3 7 4]
[ 1 1 3 17 4]
[11 1 3 7 4]]
X[:,:,1]结果输出为:
[[ 2 0 4 9 0]
[ 4 5 6 9 0]
[ 2 8 5 3 6]
[ 1 2 5 6 8]
[ 2 3 5 67 4]
[ 2 9 43 3 0]
[ 22 2 42 29 20]
[ 5 20 24 9 10]
[ 2 110 14 4 2]]
X[:,:,m:n]结果输出为:
[[[ 1]
[ 1]
[ 3]
[ 7]
[ 4]]
[[ 1]
[ 1]
[ 3]
[ 8]
[ 5]]
[[ 8]
[ 1]
[ 3]
[ 7]
[ 4]]
[[ 1]
[ 1]
[ 3]
[ 7]
[ 7]]
[[ 9]
[ 1]
[ 3]
[ 7]
[ 4]]
[[ 8]
[ 1]
[ 3]
[ 7]
[43]]
[[ 1]
[ 1]
[ 3]
[ 7]
[ 4]]
[[ 1]
[ 1]
[ 3]
[17]
[ 4]]
[[11]
[ 1]
[ 3]
[ 7]
[ 4]]]
[Finished in 0.6s]
- pic_gray = pic_and[:, :, 0]
- # print("pic_gray:",pic_gray)
- cv2.imshow("gray_pic",pic_gray)
dst = blur(src, ksize, dst=None, anchor=None, borderType=None)
均值滤波器,也称低通滤波器
顾名思义,均值滤波器即对滤波核内的数据求均值,然后将这个值赋值给矩阵核心位置。
均值滤波器可以使用cv2.blur() 方法实现src:图像
ksize:滤波核大小,使用元组表示,如(a,b)a表示height(高度),b表示width(宽度)。
anchor:波核锚点
borderType:边界类型
均值滤波效果对比:
原图:
3*3滤波:
dst1 = cv2.blur(img, (3, 3))
5*5滤波:
dst2 = cv2.blur(img, (5, 5))
10*10滤波:
dst3 = cv2.blur(img, (10, 10))
可以看出,滤波核大小越大,图像越模糊
感谢:OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器)_侯小啾的博客-CSDN博客
- pic_lowblur = cv2.blur(pic_gray, (9, 9))
- cv2.imshow("lowblur_pic",pic_lowblur)
进行9*9的均值滤波,来完成图像的平滑处理,减低噪声
《机器人学导论--分析,控制及应用》Saeed B.Niku
9.12.1 采用卷积掩模的邻域平均
- “创建一些掩模作为低通滤波器来衰减图像中的高频部分而不改变低频部分是可能实现的,这样就达到了降噪的目的”
- “掩模起到了低通滤波器的作用,它削弱了相邻像素之间的明显差异,但对强度较小的像素影响很小”
- “图像的直方图也相应地发生了改变....使图像的边缘变得平缓,使处理后的图像更加柔和,且聚焦度变低”
- “随着噪声的消除,物体的边缘也变得模糊不清”----所以引出中值滤波器
其他中值滤波器cv2.medianBlur(),高斯滤波器cv2.GussianBlur(),双边滤波器cv2.bilateralFilter(),请参考:
OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器)_侯小啾的博客-CSDN博客
阈值的作用是根据设定的值处理图像的灰度值,比如灰度大于某个数值像素点保留。通过阈值以及有关算法可以实现从图像中抓取特定的图形,比如去除背景等。
cv2中的阈值相关函数有:普通阈值函数threshold
自适应阈值函数adaptivthreshold首先介绍简单阈值函数:cv2.threshold(src, thresh, maxval, type[, dst]),返回值为retval, dst
其中:
src是灰度图像
thresh是起始阈值
maxval是最大值
type是定义如何处理数据与阈值的关系。有以下几种:
选项 像素值>thresh 其他情况 cv2.THRESH_BINARY maxval 0 cv2.THRESH_BINARY_INV 0 maxval cv2.THRESH_TRUNC thresh 当前灰度值 cv2.THRESH_TOZERO 当前灰度值 0 cv2.THRESH_TOZERO_INV 0 当前灰度值 另外的取值为:
- cv2.THRESH_OTSU
- cv2.THRESH_TRIANGLE
- cv2.THRESH_MASK
cv2.THRESH_OTSU使用最小二乘法处理像素点,而cv2.THRESH_TRIANGLE使用三角算法处理像素点。一般情况下,cv2.THRESH_OTSU适合双峰图。cv2.THRESH_TRIANGLE适合单峰图。单峰图或者双峰图指的是灰度直方图。
- (_, pic_thresh_binary) = cv2.threshold(pic_lowblur, 90, 255, cv2.THRESH_BINARY)
- cv2.imshow("pic_binary",pic_thresh_binary)
这将使像素值高于90的像素点设为maxval
Python: cv.getStructuringElement( shape, ksize[, anchor] ) -> retval
为形态学操作返回指定大小和形状的结构元素。
该函数构造并返回可进一步传递到侵蚀、扩张或形态学的结构元素。但您也可以自己构造任意的二进制掩码,并将其用作结构元素。参数
shape 元素可以是MorphShapes之一的形状
ksize 结构元素的大小。
在构件内锚定锚定位置。默认值(−1.−1) 表示锚点位于中心。请注意,只有十字形构件的形状取决于锚定位置。在其他情况下,锚只调节形态学操作结果的偏移量。MorphShapes:结构元素的形状
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
void cv::morphologyEx ( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1,-1)
,int iterations = 1
,int borderType = BORDER_CONSTANT
,const Scalar & borderValue = morphologyDefaultBorderValue()
)
函数cv::morphologyEx可以使用侵蚀和扩张作为基本操作来执行高级形态变换。
任何操作都可以就地完成。对于多通道图像,每个通道都是独立处理的。Parameters
src Source image. The number of channels can be arbitrary. The depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. dst Destination image of the same size and type as source image. op Type of a morphological operation, see MorphTypes kernel Structuring element. It can be created using getStructuringElement. anchor Anchor position with the kernel. Negative values mean that the anchor is at the kernel center. iterations Number of times erosion and dilation are applied. borderType Pixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported. borderValue Border value in case of a constant border. The default value has a special meaning.
- pic_morphologyEx = cv2.morphologyEx(pic_thresh_binary, cv2.MORPH_CLOSE, kernel)
- cv2.imshow("morphologyEx_pic",pic_morphologyEx)
void cv::erode ( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1)
,int iterations = 1
,int borderType = BORDER_CONSTANT
,const Scalar & borderValue = morphologyDefaultBorderValue()
使用特定的结构元素侵蚀图像。
The function erodes the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the minimum is taken:
dst(x,y)=min(x′,y′):element(x′,y′)≠0src(x+x′,y+y′)
The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In case of multi-channel images, each channel is processed independently.
Parameters
src input image; the number of channels can be arbitrary, but the depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. dst output image of the same size and type as src. kernel structuring element used for erosion; if element=Mat()
, a3 x 3
rectangular structuring element is used. Kernel can be created using getStructuringElement.anchor position of the anchor within the element; default value (-1, -1) means that the anchor is at the element center. iterations number of times erosion is applied. borderType pixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported. borderValue border value in case of a constant border
- pic_erode = cv2.erode(pic_morphologyEx, None, iterations=4)
- cv2.imshow("erode_pic",pic_erode)
void cv::dilate ( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1)
,int iterations = 1
,int borderType = BORDER_CONSTANT
,const Scalar & borderValue = morphologyDefaultBorderValue()
)
使用特定的结构元素放大图像。
The function dilates the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the maximum is taken:
dst(x,y)=max(x′,y′):element(x′,y′)≠0src(x+x′,y+y′)
The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In case of multi-channel images, each channel is processed independently.
Parameters
src input image; the number of channels can be arbitrary, but the depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. dst output image of the same size and type as src. kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular structuring element is used. Kernel can be created using getStructuringElement anchor position of the anchor within the element; default value (-1, -1) means that the anchor is at the element center. iterations number of times dilation is applied. borderType pixel extrapolation method, see BorderTypes. BORDER_WRAP is not suported. borderValue border value in case of a constant border
- pic_dilate = cv2.dilate(pic_erode, None, iterations=4)
- cv2.imshow("dilate_pic",pic_dilate)
重点参考: OpenCV: OpenCV moduleshttps://docs.opencv.org/4.5.5/index.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。