• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

opencv与numpy的图像基本操作

python 搞代码 4年前 (2022-01-08) 47次浏览 已收录 0个评论

这篇文章主要介绍了opencv与numpy的图像基本操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 像素基本操作

1.1 读取、修改像素

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

 >>> import cv2 >>> import numpy as np >>> img = cv2.imread('messi5.jpg-600')
 >>> px = img[100,100] >>> print( px ) [157 166 200] # accessing only blue pixel >>> blue = img[100,100,0] >>> print( blue ) 157

可以直接通过坐标修改像素值

 >>> img[100,100] = [255,255,255] >>> print( img[100,100] ) [255 255 255]

然而直接像上面这样去读取、修改每个像素的值,效率是比较低的,可以使用下面的方法,效率是更高的

 # 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 读取图像属性

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

 >>> print( img.shape ) (342, 548, 3)

读取像素大小, 行 通道数

 >>> print( img.size ) 562248

像素数据类型

 >>> print( img.dtype ) uint8

1.3 图像ROI操作

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

 import cv2 import numpy as np img = cv2.imread("test.jpg-600") p<mark style="color:transparent">来源gaodaimacom搞#^代%!码网</mark>rint(img.shape) roiTest = img[475:525, 0:50] img[0:50, 0:50] = roiTest cv2.imshow("image",img) cv2.waitKey(0)

1.4 分割、合并通道

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

 >>> b,g,r = cv2.split(img) >>> img = cv2.merge((b,g,r))

或者

 b = img[:,:,0]

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

1.4 生成图像边框

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

 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时的边框像素 ) 

 BLUE = [255, 0, 0] img1 = cv2.imread("test.jpg-600") 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()

 

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

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

2. 图像的基本算术操作

2.1 图像相加

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

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

 >>> 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等参数

 void cv::add ( InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1 ) 

2.2 图像混合

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

dst=α⋅img1+β⋅img2+γ

 img1 = cv2.imread('ml.png-600') img2 = cv2.imread('opencv-logo.png-600') dst = cv2.addWeighted(img1,0.7,img2,0.3,0) cv2.imshow('dst',dst) cv2.waitKey(0) cv2.destroyAllWindows()

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

以上就是opencv与numpy的图像基本操作的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:opencv与numpy的图像基本操作

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址