【学习笔记】ROS 中常用opencv操作

self.sub = rospy.Subscriber("/camera/rgb/image_raw", Image, self.image_cb, queue_size=1)
  • CvBridge().imgmsg_to_cv2():ROS image消息类型到opencv类型的转换

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)
  • cv2.cvtColor():RGB颜色向HSV空间转换

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_BGRA2RGBA

2、向RGB和BGR图像中增添alpha通道

cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA

3、从RGB和BGR图像中去除alpha通道

cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR

4、从RBG和BGR颜色空间转换到灰度空间

cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAY

cv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY

5、从灰度空间转换到RGB和BGR颜色空间

cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGR

cv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA

6、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_BGR5652BGRA

7、灰度空间域BGR565之间的转换

cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY

8、RGB和BGR颜色空间与CIE XYZ之间的转换

cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR

9、RGB和BGR颜色空间与uma色度(YCrCb空间)之间的转换

cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR

10、RGB和BGR颜色空间与HSV颜色空间之间的相互转换

cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR

11、RGB和BGR颜色空间与HLS颜色空间之间的相互转换

cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR

12、RGB和BGR颜色空间与CIE Lab颜色空间之间的相互转换

cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGB

cv::COLOR_Lab2BGR

13、RGB和BGR颜色空间与CIE Luv颜色空间之间的相互转换

cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR

14、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.arrray():构造数组,以存储色块HSV阈值范围

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

此处把部分红色归为紫色范围:

  • cv2.inRange():阈值处理

mask = cv2.inRange(pic_hsv, LowerBlue, UpperBlue)
cv2.imshow("black&white",mask)

cv_image2:原图或者指要进行处理的图

LowerBlue:由上面确定下来的阈值处理,低于这个值的将变为0,即黑色

UpperBlue:同样是由上面确定的阈值,高于这个值将转变成0,即黑色

在LowerBlue~UpperBlue之间的值将转变成255,即白色

因为我采用的是检测蓝色,所以处理结束后图形中蓝色部分将变为白色,其他部分变为黑色,形成黑白二值图,mask就是处理后的图

  •  cv2.bitwise_and():位运算,对图像进行掩模

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 opencv 计算机视觉零基础到实战] 七、逻辑运算与应用_1_bit的博客-CSDN博客

  • X[:,:,0]:是取三维矩阵中第一维的所有数据

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]

感谢:https://www.jb51.net/article/180301.htm

pic_gray = pic_and[:, :, 0]
# print("pic_gray:",pic_gray)
cv2.imshow("gray_pic",pic_gray)

  • cv2.blur():均值滤波

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():简单阈值函数

阈值的作用是根据设定的值处理图像的灰度值,比如灰度大于某个数值像素点保留。通过阈值以及有关算法可以实现从图像中抓取特定的图形,比如去除背景等。


cv2中的阈值相关函数有:

    普通阈值函数threshold
    自适应阈值函数adaptivthreshold

首先介绍简单阈值函数:cv2.threshold(src, thresh, maxval, type[, dst]),返回值为retval, dst

其中:
src是灰度图像
thresh是起始阈值
maxval是最大值
type是定义如何处理数据与阈值的关系。有以下几种:

选项像素值>thresh其他情况
cv2.THRESH_BINARYmaxval0
cv2.THRESH_BINARY_INV0maxval
cv2.THRESH_TRUNCthresh当前灰度值
cv2.THRESH_TOZERO当前灰度值0
cv2.THRESH_TOZERO_INV0当前灰度值

另外的取值为:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE
  • cv2.THRESH_MASK

cv2.THRESH_OTSU使用最小二乘法处理像素点,而cv2.THRESH_TRIANGLE使用三角算法处理像素点。一般情况下,cv2.THRESH_OTSU适合双峰图。cv2.THRESH_TRIANGLE适合单峰图。单峰图或者双峰图指的是灰度直方图。

感谢:CV2简单阈值函数:cv2.threshold()_风华明远的博客-CSDN博客_cv2.threshold()

    (_, pic_thresh_binary) = cv2.threshold(pic_lowblur, 90, 255, cv2.THRESH_BINARY)
    cv2.imshow("pic_binary",pic_thresh_binary)

这将使像素值高于90的像素点设为maxval

  •      cv2.getStructuringElement:获取结构元素

Mat cv::getStructuringElement(int shape,
Sizeksize,
Pointanchor = Point(-1,-1) 
)
Python:
cv.getStructuringElement(shape, ksize[, anchor]) ->

retval

为形态学操作返回指定大小和形状的结构元素。
该函数构造并返回可进一步传递到侵蚀、扩张或形态学的结构元素。但您也可以自己构造任意的二进制掩码,并将其用作结构元素。

参数
shape 元素可以是MorphShapes之一的形状
ksize   结构元素的大小。
在构件内锚定锚定位置。默认值(−1.−1) 表示锚点位于中心。请注意,只有十字形构件的形状取决于锚定位置。在其他情况下,锚只调节形态学操作结果的偏移量。

MorphShapes:结构元素的形状

MORPH_RECT 

Python: cv.MORPH_RECT

a rectangular structuring element:

Eij=1

MORPH_CROSS 

Python: cv.MORPH_CROSS

a cross-shaped structuring element:

Eij={10if i=anchor.y orj=anchor.xotherwise

MORPH_ELLIPSE 

Python: cv.MORPH_ELLIPSE

an elliptic structuring element, that is, a filled ellipse inscribed into the rectangle Rect(0, 0, esize.width, 0.esize.height)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
  • morphologyEx():执行高级形态变换

void cv::morphologyEx(InputArraysrc,
OutputArraydst,
int op,
InputArraykernel,
Pointanchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const ScalarborderValue = morphologyDefaultBorderValue() 
)

函数cv::morphologyEx可以使用侵蚀和扩张作为基本操作来执行高级形态变换。


任何操作都可以就地完成。对于多通道图像,每个通道都是独立处理的。

Parameters

srcSource 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.
dstDestination image of the same size and type as source image.
opType of a morphological operation, see MorphTypes
kernelStructuring element. It can be created using getStructuringElement.
anchorAnchor position with the kernel. Negative values mean that the anchor is at the kernel center.
iterationsNumber of times erosion and dilation are applied.
borderTypePixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported.
borderValueBorder 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)

  • cv2.erode():腐蚀操作

void cv::erode(InputArraysrc,
OutputArraydst,
InputArraykernel,
Pointanchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const ScalarborderValue = 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

srcinput 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.
dstoutput image of the same size and type as src.
kernelstructuring element used for erosion; if element=Mat(), a 3 x 3 rectangular structuring element is used. Kernel can be created using getStructuringElement.
anchorposition of the anchor within the element; default value (-1, -1) means that the anchor is at the element center.
iterationsnumber of times erosion is applied.
borderTypepixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported.
borderValueborder value in case of a constant border
pic_erode = cv2.erode(pic_morphologyEx, None, iterations=4)
cv2.imshow("erode_pic",pic_erode)

 

  •  cv2.dilates():扩张操作

void cv::dilate(InputArraysrc,
OutputArraydst,
InputArraykernel,
Pointanchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const ScalarborderValue = 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

srcinput 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.
dstoutput image of the same size and type as src.
kernelstructuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular structuring element is used. Kernel can be created using getStructuringElement
anchorposition of the anchor within the element; default value (-1, -1) means that the anchor is at the element center.
iterationsnumber of times dilation is applied.
borderTypepixel extrapolation method, see BorderTypes. BORDER_WRAP is not suported.
borderValueborder 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

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年5月24日 下午12:07
下一篇 2022年5月24日

相关推荐