当前位置:脚本大全 > > 正文

opencv图像识别基础知识(opencv与numpy的图像基本操作)

时间:2022-01-20 00:38:48类别:脚本大全

opencv图像识别基础知识

opencv与numpy的图像基本操作

1. 像素基本操作

1.1 读取、修改像素

可以通过[行,列]坐标来访问像素点数据,对于多通道数据,返回一个数组,包含所有通道的值,对于单通道数据(如gray),返回指定坐标的值,也可以通过 [行,列,通道index] 来访问某坐标某通道的值。

  • ?
  • 1
  • 2
  • 3
  • >>> import cv2
  • >>> import numpy as np
  • >>> img = cv2.imread('messi5.jpg" alt="opencv图像识别基础知识(opencv与numpy的图像基本操作)" border="0" />)
  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • >>> px = img[100,100]
  • >>> print( px )
  • [157 166 200]
  • # accessing only blue pixel
  • >>> blue = img[100,100,0]
  • >>> print( blue )
  • 157
  • 可以直接通过坐标修改像素值

  • ?
  • 1
  • 2
  • 3
  • >>> img[100,100] = [255,255,255]
  • >>> print( img[100,100] )
  • [255 255 255]
  • 然而直接像上面这样去读取、修改每个像素的值,效率是比较低的,可以使用下面的方法,效率是更高的

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • # accessing red value
  • >>> img.item(10,10,2)
  • 59
  • # modifying red value
  • >>> img.itemset((10,10,2),100)
  • >>> img.item(10,10,2)
  • 100
  • 1.2 读取图像属性

    读取图像尺寸,返回一个元组 (行,列,通道数)

  • ?
  • 1
  • 2
  • >>> print( img.shape )
  • (342, 548, 3)
  • 读取像素大小, 行 通道数

  • ?
  • 1
  • 2
  • >>> print( img.size )
  • 562248
  • 像素数据类型

  • ?
  • 1
  • 2
  • >>> print( img.dtype )
  • uint8
  • 1.3 图像roi操作

    可以直接编辑像素区域,例如把图像左下角50*50的像素复制到左上角

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • import cv2
  • import numpy as np
  • img = cv2.imread("test.jpg" alt="opencv图像识别基础知识(opencv与numpy的图像基本操作)" border="0" />)
  • print(img.shape)
  • roitest = img[475:525, 0:50]
  • img[0:50, 0:50] = roitest
  • cv2.imshow("image",img)
  • cv2.waitkey(0)
  • opencv图像识别基础知识(opencv与numpy的图像基本操作)

    1.4 分割、合并通道

    有些情况下需要对图像的某一通道数据进行操作,此时会用到分割、合并通道数据

  • ?
  • 1
  • 2
  • >>> b,g,r = cv2.split(img)
  • >>> img = cv2.merge((b,g,r))
  • 或者

  • ?
  • 1
  • b = img[:,:,0]
  • 假设想编辑红色通道的数据,全部设置为0,不需要这样分割后编辑, img[:,:,2] = 0 这样即可。cv2.split操作是一个很耗时的操作,可以用numpy索引替代的操作,尽量用numpy索引来做。

    1.4 生成图像边框

    使用 cv2.copymakeborder 函数可添加图像边框,支持多种边框算法

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • void cv::copymakeborder (
  • inputarray src, //原图
  • //目标图(cpp版本中,若传入此数据且选border_transparent,则此数据被top/bottom/left/right切出来的roi部分不会被做任何修改,此图像大小=dst.rows+top+bottom,dst.cols+left+right)
  • outputarray dst,
  • int top, //top/left/bottom/right 四个方向上的边框像素
  • int bottom,
  • int left,
  • int right,
  • int bordertype, //边框类型见下图
  • const scalar & value = scalar() //边框类型为border_constant时的边框像素
  • )
  • opencv图像识别基础知识(opencv与numpy的图像基本操作)

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • blue = [255, 0, 0]
  •  img1 = cv2.imread("test.jpg" alt="opencv图像识别基础知识(opencv与numpy的图像基本操作)" border="0" />)
  •  replicate = cv2.copymakeborder(img1, 100, 100, 100, 100, cv2.border_replicate)
  •  reflect = cv2.copymakeborder(img1, 100, 100, 100, 100, cv2.border_reflect)
  •  reflect101 = cv2.copymakeborder(img1, 100, 100, 100, 100, cv2.border_reflect_101)
  •  wrap = cv2.copymakeborder(img1, 100, 100, 100, 100, cv2.border_wrap)
  •  constant = cv2.copymakeborder(img1, 100, 100, 100, 100, cv2.border_constant, value=blue)
  •  print(img1.shape, reflect.shape)
  •  plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('original')
  •  plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('replicate')
  •  plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('reflect')
  •  plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('reflect_101')
  •  plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('wrap')
  •  plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('constant')
  •  plt.show()
  • opencv图像识别基础知识(opencv与numpy的图像基本操作)

    上面的例子可以比较直观的看到各种border的效果,同时也能发现,python版的api与cpp版本的相比,默认初始化了一块原始图尺寸+各方向边框尺寸的图像内存,作为内置的dst参数。

    输出尺寸:(525, 700, 3) (725, 900, 3)

    2. 图像的基本算术操作

    2.1 图像相加

    图像相加,两个图像应该有相同的shape,或者图像和一个标量相加,或者图像和一个与其通道数相同的一维数组相加。

    opencv的相加与numpy相加时,在超出数据类型范围时的处理不同

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • >>> x = np.uint8([250])
  • >>> y = np.uint8([10])
  • >>> print( cv2.add(x,y) ) # 250+10 = 260 => 255
  • [[255]]
  • >>> print( x+y )  # 250+10 = 260 % 256 = 4
  • [4]
  • cpp版本的api还支持mask等参数

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • void cv::add (
  • inputarray src1,
  • inputarray src2,
  • outputarray dst,
  • inputarray mask = noarray(),
  • int dtype = -1
  • )
  • 2.2 图像混合

    opencv通过 cv::addweighted 函数提供了将两个图像混合在一起的方法

    dst=α⋅img1+β⋅img2+γ

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • img1 = cv2.imread('ml.jpg" alt="opencv图像识别基础知识(opencv与numpy的图像基本操作)" border="0" />)
  • img2 = cv2.imread('opencv-logo.jpg" alt="opencv图像识别基础知识(opencv与numpy的图像基本操作)" border="0" />)
  • dst = cv2.addweighted(img1,0.7,img2,0.3,0)
  • cv2.imshow('dst',dst)
  • cv2.waitkey(0)
  • cv2.destroyallwindows()
  • opencv图像识别基础知识(opencv与numpy的图像基本操作)

    通过cv2.seamlessclone函数还能做更精细的图像局部融合。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。

    原文链接:https://www.zoucz.com/blog/2019/03/07/50ef43b0-40a5-11e9-9947-3d7b79f522a2/

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐