干货 | OpenCV看这篇就够了,9段代码详解图像变换基本操作

作者 | 王天庆,长期从事分布式系统、数据科学与工程、人工智能等方面的研究与开发,在人脸识别方面有丰富的实践经验。现就职某世界100强企业的数据实验室,从事数据科学相关技术领域的预研工作。
来源 | 大数据(ID:hzdashuju)
01 OpenCV介绍
pip install opencv-pythonconda install opencv# 查看引入OpenCV库时是否报错import cv2# 查看安装的版本cv2.__version__# 我这里显示的版本信息是 '3.4.1'


- 代码清单① OpenCV中图片的读取和存储
import cv2import numpy as np# 使用imread()方法读入一个图片image = cv2.imread("lena.jpg")# 看一下数据的存储维度image.shape# 返回:(121, 121, 3)# 将读入的数据image打印出来print(image)'''如果读入数据失败,返回值将不是一个array类型,而是None我们可以看到图片数据的存储形式:[[[113 152 227][109 153 230][104 152 230]...,[ 58 93 166][119 156 212][149 182 232]][[107 149 224][103 149 226][ 97 149 225]...,[ 79 112 175][ 77 108 159][ 65 91 137]][[101 148 222][ 96 146 222][ 91 146 221]...,[ 56 80 132][ 3 22 65][ 0 3 40]]...,[[ 21 40 45][ 24 37 45][ 34 41 50]...,[ 20 34 57][ 7 24 50][ 8 27 54]][[ 17 35 36][ 20 32 38][ 22 29 38]...,[ 13 29 52][ 28 45 72][ 41 59 90]][[ 15 31 30][ 19 31 35][ 21 28 37]...,[ 13 29 52][ 48 64 93][ 71 90 123]]]'''# 将存储图片数据的image变量写到磁盘中,写出的文件名为lena.bak.jpg# 其返回值结果为True代表写入成功,反之代表失败cv2.imwrite("lena.bak.jpg",image)
could not find a writer for the specified extension in function cv::imwrite_- 代码清单② 使用OpenCV将图片灰度化处理
import numpy as npimport cv2img = cv2.imread("lena.jpg")print(img.shape)# (121, 121, 3)# 使用cv2.cvtColor() 方法将彩色图片转换为灰度图片gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)print(gray_img.shape)# (121, 121)# 将转换后的灰度图片回复成BGR形式img2 = cv2.cvtColor(gray_img,cv2.COLOR_GRAY2BGR)print(img2.shape)# (121, 121, 3)# 输出彩色图片img的内容print(img)'''[[[113 152 227][109 153 230][104 152 230]...,[ 58 93 166][119 156 212][149 182 232]][[107 149 224][103 149 226][ 97 149 225]...,[ 79 112 175][ 77 108 159][ 65 91 137]][[101 148 222][ 96 146 222][ 91 146 221]...,[ 56 80 132][ 3 22 65][ 0 3 40]]...,[[ 21 40 45][ 24 37 45][ 34 41 50]...,[ 20 34 57][ 7 24 50][ 8 27 54]][[ 17 35 36][ 20 32 38][ 22 29 38]...,[ 13 29 52][ 28 45 72][ 41 59 90]][[ 15 31 30][ 19 31 35][ 21 28 37]...,[ 13 29 52][ 48 64 93][ 71 90 123]]]'''# 输出将灰度图片重新转换为BGR形式图片后的内容print(img2)'''[[[170 170 170][171 171 171][170 170 170]...,[111 111 111][169 169 169][193 193 193]][[167 167 167][167 167 167][166 166 166]...,[127 127 127][120 120 120][102 102 102]][[165 165 165][163 163 163][162 162 162]...,[ 93 93 93][ 33 33 33][ 14 14 14]]...,[[ 39 39 39][ 38 38 38][ 43 43 43]...,[ 39 39 39][ 30 30 30][ 33 33 33]][[ 33 33 33][ 32 32 32][ 31 31 31]...,[ 34 34 34][ 51 51 51][ 66 66 66]][[ 29 29 29][ 31 31 31][ 30 30 30]...,[ 34 34 34][ 71 71 71][ 98 98 98]]]'''
- 代码清单③ 负片功能实现
import numpy as npimport cv2# 读入图片img = cv2.imread("lena.jpg")# 获取高度和宽度,注意索引是高度在前,宽度在后height = img.shape[0]width = img.shape[1]# 生成一个空的三维张量,用于存放后续三个通道的数据negative_file = np.zeros((height,width,3))# 将BGR形式存储的彩色图片拆分成三个颜色通道,注意颜色通道的顺序是蓝、绿、红b,g,r = cv2.split(img)# 进行负片化处理,求每个通道颜色的补色r = 255 - rb = 255 - bg = 255 - g# 将处理后的结果赋值到前面生成的三维张量中negative_file[:,:,0] = bnegative_file[:,:,1] = gnegative_file[:,:,2] = r# 看一下生成图片的数据negative_file'''array([[[ 142., 103., 28.],[ 146., 102., 25.],[ 151., 103., 25.],...,[ 197., 162., 89.],[ 136., 99., 43.],[ 106., 73., 23.]],[[ 148., 106., 31.],[ 152., 106., 29.],[ 158., 106., 30.],...,[ 176., 143., 80.],[ 178., 147., 96.],[ 190., 164., 118.]],[[ 154., 107., 33.],[ 159., 109., 33.],[ 164., 109., 34.],...,[ 199., 175., 123.],[ 252., 233., 190.],[ 255., 252., 215.]],...,[[ 234., 215., 210.],[ 231., 218., 210.],[ 221., 214., 205.],...,[ 235., 221., 198.],[ 248., 231., 205.],[ 247., 228., 201.]],[[ 238., 220., 219.],[ 235., 223., 217.],[ 233., 226., 217.],...,[ 242., 226., 203.],[ 227., 210., 183.],[ 214., 196., 165.]],[[ 240., 224., 225.],[ 236., 224., 220.],[ 234., 227., 218.],...,[ 242., 226., 203.],[ 207., 191., 162.],[ 184., 165., 132.]]])'''# 将生成的图片保存起来,注意存储图片文件名中的扩展名cv2.imwrite("negative_lena.jpg",negative_file)

- 点算子:基于像素变换,在这一类图像变换中,仅仅根据输入像素值(有时可加上某些额外信息)计算相应的输出像素值。
- 邻域算子:基于图像区域进行变换。
- 代码清单④ 对图片亮度与对比度转换演示
import cv2import numpy as np# 方法1:通过addWeighted()函数来实现def convert_img1(img, alpha, beta):blank = np.zeros(img.shape, img.dtype) # dtpye is uint8return cv2.addWeighted(img, alpha, blank, 0, beta)# 方法2: 通过for循环手动实现,与addWeighted()函数内部实现原理一样def convert_img2(img, alpha, beta):rows, cols, channel = img.shapenew_img = np.zeros(img.shape, img.dtype)for i in range(0,rows):for j in range(0,cols):for k in range(0,channel):# np.clip() 将数值限制在[0,255]区间,防止数字溢出new_img[i,j,k] = np.clip(alpha * img[i,j,k] + beta,0,255)return new_imgimg = cv2.imread('lena.jpg')cv2.imwrite('converted_lena_1.jpg', convert_img1(img,2.2,50))cv2.imwrite('converted_lena_2.jpg', convert_img2(img,2.2,50))

- 代码清单⑤ 图像裁剪演示
import cv2import numpy as npimg = cv2.imread('lena.jpg')print(img.shape)# (121, 121, 3)new_img = img[20:120,20:120]cv2.imwrite('new_img.jpg',new_img)

- 代码清单⑥ 使用OpenCV变换图像尺寸
import cv2import numpy as npimg = cv2.imread('lena.jpg')print(img.shape)# (121, 121, 3)new_img = cv2.resize(img,(40,40),interpolation=cv2.INTER_AREA)cv2.imwrite('new_img1.jpg', new_img)print(new_img.shape)# (40, 40, 3)new_img2 = cv2.resize(img,None,fx=0.5, fy=0.6,interpolation=cv2.INTER_AREA)print(new_img2.shape)# 注意图像的宽对应的是列数,高对应的是行数# (73, 60, 3)cv2.imwrite('new_img2.jpg',new_img2)

- 代码清单⑦ 使用OpenCV实现图像旋转
import cv2import numpy as npimg = cv2.imread('lena.jpg')rows, cols, _ = img.shape# 第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子rotated_img = cv2.getRotationMatrix2D((cols/2,rows/2),45,0.4)cv2.imwrite('dst.jpg',dst)

- 代码清单⑧ 为图像添加噪声
import cv2import numpy as npimport random# 添加椒盐噪声def salt_and_pepper_noise(img, percentage):rows, cols = img.shapenum = int(percentage * rows * cols)for i in range(num):x = random.randint(0,rows - 1)y = random.randint(0,cols - 1)if random.randint(0,1) == 0:img[x,y] = 0else:img[x,y] = 255return img# 添加高斯随机噪声def gaussian_noise(img, mu, sigma, k):rows, cols = img.shapefor i in range(rows):for j in range(cols):# 生成高斯分布的随机数,与原始数据相加后要取整value = int(img[i,j] + k * random.gauss(mu=mu,sigma=sigma))value = np.clip(a_max=255,a_min=0,a=value)img[i,j] = valuereturn imgimg = cv2.imread('lena.jpg')# 转换为灰度图像gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)cv2.imwrite('gray_lena.jpg',gray_img)# 需要复制一份,不然是对图像的引用,后面的操作会重叠gray_img2 = gray_img.copy()# 保存椒盐噪声图像cv2.imwrite('salt_and_pepper.jpg',salt_and_pepper_noise(gray_img,0.3))# 保存高斯噪声图像cv2.imwrite('gaussian.jpg',gaussian_noise(gray_img2, 0, 1, 32))

- 代码清单⑨ 图像滤波演示
import cv2import numpy as npimport randomsalt_and_pepper_img = cv2.imread('salt_and_pepper.jpg')gaussian_img = cv2.imread('gaussian.jpg')# 2维卷积# 得到一个5*5大小的矩阵作为卷积核,矩阵中的每个值都为0.04kernel = np.ones((5,5),np.float32) / 25conv_2d_img = cv2.filter2D(salt_and_pepper_img, -1, kernel)cv2.imwrite('filter_2d_img.jpg', conv_2d_img)# 中值滤波# 参数5表示选择附近5*5区域的像素值进行计算median_blur_img = cv2.medianBlur(salt_and_pepper_img,5)cv2.imwrite('median_blur_img.jpg', median_blur_img)# 高斯模糊# 标准差参数设置为0是指根据窗口大小(5,5)来自行计算高斯函数标准差gaussian_blur_img = cv2.GaussianBlur(gaussian_img, (5,5), 0)cv2.imwrite('gaussian_blur_img.jpg', gaussian_blur_img)# 双边滤波# cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)# 9 代表邻域直径,两个参数75分别代表值域与空域标准差bilateral_filter_img = cv2.bilateralFilter(gaussian_img, 9, 75, 75)cv2.imwrite('bilateral_filter_img.jpg', bilateral_filter_img)
- 对添加过椒盐噪声图片经过二维卷积滤波后的结果
- 对添加过椒盐噪声图片进行中值滤波后的结果
- 对经过高斯噪声污染后的图片进行高斯滤波后的结果
- 对经过高斯噪声污染后的图片进行双边滤波后的结果


推荐阅读
一份职位信息的精准推荐之旅,从AI底层架构说起
Uber提出损失变化分配方法LCA,揭秘神经网络“黑盒”
阿里云智能运维的自动化三剑客
掌握这些步骤,机器学习模型问题药到病除
6张拓扑图揭秘中心化交易所的5种行为, 原来中心化比你想象的重要!
分布式存储春天已来Storj首登top10; Cardano排名上升; 以太坊比特币活跃地址双下降 | 数据周榜
华为愿出售5G技术渴望对手;苹果将向印度投资10亿美元;华为全联接大会首发计算战略;腾讯自研轻量级物联网操作系统正式开源……
TDD 就是个坑!
我愿出 2 倍工资,挖这个被裁的程序员!
厉害!接班马云的为何是张勇?

你点的每个“在看”,我都认真当成了喜欢“
相关文章:

C++/C++11中std::priority_queue的使用
std::priority_queue:在优先队列中,优先级高的元素先出队列,并非按照先进先出的要求,类似一个堆(heap)。其模板声明带有三个参数,priority_queue<Type, Container, Functional>, 其中Type为数据类型,Container为…

left join 和 left outer join 的区别
老是混淆,做个笔记,转自:https://www.cnblogs.com/xieqian111/p/5735977.html left join 和 left outer join 的区别 通俗的讲: A left join B 的连接的记录数与A表的记录数同 A right join B 的连接的记录数与…

php减少损耗的方法之一 缓存对象
即把实例后的对象缓存起来(存入变量),当需要再次实例化时,先去缓存里查看是否存在。存在则返回。否则实例化。转载于:https://www.cnblogs.com/zuoxiaobing/p/3581139.html
windows10 vs2013控制台工程中添加并编译cuda8.0文件操作步骤
一般有两种方法可以在vs2013上添加运行cuda8.0程序:一、直接新建一个基于CUDA8.0的项目:如下图所示,点击确定后即可生成test_cuda项目;默认会自动生成一个kernel.cu文件;默认已经配置好Debug/Release, Win32/x64环境&a…

算法人必懂的进阶SQL知识,4道面试常考题
(图片付费下载自视觉中国)作者 | 石晓文来源|小小挖掘机(ID:wAlsjwj)近期在不同群里有小伙伴们提出了一些在面试和笔试中遇到的Hive SQL问题,Hive作为算法工程师的一项必备技能,在面…

007-迅雷定时重启AutoHotkey脚本-20190411
;; 定时重启迅雷.ahk,;;~ 2019年04月11日;#SingleInstance,forceSetWorkingDir,%A_ScriptDir%DetectHiddenWindows,OnSetTitleMatchMode,2#Persistent ;让脚本持久运行(即直到用户关闭或遇到 ExitApp)。#NoEnv;~ #NoTrayIcon Hotkey,^F10,ExitThisApp lo…

关于ExtJS在使用下拉列表框的二级联动获取数据
2019独角兽企业重金招聘Python工程师标准>>> 使用下拉列表框的二级联动获取数据,如果第一个下拉列表框有默认值时,需要设置fireEvent执行select事件 示例: var combo Ext.getCmp("modifyBuildCom"); combo.setValue(re…

C++中std::sort/std::stable_sort/std::partial_sort的区别及使用
某些算法会重排容器中元素的顺序,如std::sort。调用sort会重排输入序列中的元素,使之有序,它默认是利用元素类型的<运算符来实现排序的。也可以重载sort的默认排序,即通过sort的第三个参数,此参数是一个谓词(predic…

阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...
作者 | 屠敏受访者 | 丁险峰来源 | CSDN(ID:CSDNnews)「忽如一夜春风来,千树万树梨花开。」从概念的流行、至科技巨头的相继入局、再到诸多应用的落地,IoT 的发展终于在万事俱备只欠东风的条件下真正地迎来了属于自己的…

eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析...
Guide: eBCC性能分析最佳实践(0) - 开启性能分析新篇章eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析eBCC性能分析最佳实践(2) - 一个简单的eBCC分析网络函数的latency敬请期待...0. I…

spring-data-mongodb必须了解的操作
http://docs.spring.io/spring-data/data-mongo/docs/1.0.0.M5/api/org/springframework/data/mongodb/core/MongoTemplate.html 在线api文档 1关键之识别 KeywordSampleLogical resultGreaterThanfindByAgeGreaterThan(int age){"age" : {"$gt" : age}}Le…

旷视张祥雨:高效轻量级深度模型的研究和实践 | AI ProCon 2019
演讲嘉宾 | 张祥雨(旷视研究院主任研究员、基础模型组负责人)编辑 | Just出品 | AI科技大本营(ID:rgznai100)基础模型是现代视觉识别系统中一个至关重要的关注点。基础模型的优劣主要从精度、速度或功耗等角度判定,如何…

Python脱产8期 Day02
一 语言分类 机器语言,汇编语言,高级语言(编译和解释) 二 环境变量 1、配置环境变量不是必须的2、配置环境变量的目的:为终端提供执行环境 三Python代码执行的方式 1交互式:.控制台直接编写运行python代码 …
分别用Eigen和C++(OpenCV)实现图像(矩阵)转置
(1)、标量(scalar):一个标量就是一个单独的数。(2)、向量(vector):一个向量是一列数,这些数是有序排列的,通过次序中的索引,可以确定每个单独的数。(3)、矩阵(matrix):矩阵是一个二维数组,其中的…

Linux基础优化
***************************************************************************************linux系统的优化有很多,我简单阐述下我经常优化的方针:记忆口诀:***********************一清、一精、一增;两优、四设、七其他。*****…
数据集cifar10到Caffe支持的lmdb/leveldb转换的实现
在 http://blog.csdn.net/fengbingchun/article/details/53560637 对数据集cifar10进行过介绍,它是一个普通的物体识别数据集。为了使用Caffe对cifar10数据集进行train,下面实现了将cifar10到lmdb/leveldb的转换实现:#include "funset.h…

计算两个时间的间隔时间是多少
/*** 计算两个时间间隔* param startTime 开始时间* param endTime 结束时间* param type 类型(1:相隔小时 2:)* return*/public static int compareTime(String startTime, String endTime, int type) {if (endTime nul…

作为西二旗程序员,我是这样学习的.........
作为一名合格的程序员,需要时刻保持对新技术的敏感度,并且要定期更新自己的技能储备,是每个技术人的日常必修课。但要做到这一点,知乎上的网友说最高效的办法竟然是直接跟 BAT 等一线大厂取经。讲真的,BAT大厂的平台是…

2月国内搜索市场:360继续上升 百度下降0.62%
IDC评述网(idcps.com)03月06日报道:根据CNZZ数据显示,在国内搜索引擎市场中,百度在2014年2月份所占的份额继续被蚕食,环比1月份,下降了0.62%,为60.50%。与此相反,360搜索…

不止于刷榜,三大CV赛事夺冠算法技术的“研”与“用”
(由AI科技大本营付费下载自视觉中国)整理 | Jane出品 | AI科技大本营(ID:rgznai100)在 5 个月时间里(5月-9月),创新工场旗下人工智能企业创新奇智连续在世界顶级人脸检测竞赛 WIDER …
Ubuntu14.04上编译指定版本的protobuf源码操作步骤
Google Protobuf的介绍可以参考 http://blog.csdn.net/fengbingchun/article/details/49977903 ,这里介绍在Ubuntu14.04上编译安装指定版本的protobuf的操作步骤,这里以2.4.1为例:1. Ubuntu14.04上默认安装的是2.5.0,…

Linux下,各种解压缩命令集合
Linux下,各种解压缩命令集合tar xvfj lichuanhua.tar.bz2tar xvfz lichuanhua.tar.gztar xvfz lichuanhua.tgztar xvf lichuanhua.tarunzip lichuanhua.zip.gz解压 1:gunzip FileName.gz解压 2:gzip -d FileName.gz压缩:gzip File…
gtest使用初级指南
之前在 http://blog.csdn.net/fengbingchun/article/details/39667571 中对google的开源库gtest进行过介绍,现在看那篇博文,感觉有些没有说清楚,这里再进行总结下:Google Test是Google的开源C单元测试框架,简称gtest。…

iOS视频流采集概述(AVCaptureSession)
需求:需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪,旋转,美颜,特效....). 所以,必须采集到视频帧数据. 阅读前提: 使用AVFoundation框架采集音视频帧数据GitHub地址(附代码) : iOS视频流采集概述 简书地址 : iOS视频流采…

300秒搞定第一超算1万年的计算量,量子霸权时代已来?
(由AI科技大本营付费下载自视觉中国)作者 | 马超责编 | 郭芮来源 | CSDN 博客近日,美国航天局(NASA)发布了一篇名为《Quantum Supremacy Using a Programmable Superconducting Processor》的报道,称谷歌的…

2014-3-6 星期四 [第一天执行分析]
昨日进度: [毛思想]:看测控技术量待定 --> [良]超额完成,昨天基本上把测控看了一大半啦 [汇编]:认真听课,边听边消化自学 --> [中]基本满足,还需要抽时间总结,特别是前面寻址的各种情况…
行列式介绍及Eigen/OpenCV/C++的三种实现
行列式,记作det(A),是一个将方阵A映射到实数的函数。行列式等于矩阵特征值的乘积。行列式的绝对值可以用来衡量矩阵参与矩阵乘法后空间扩大或者缩小了多少。如果行列式是0,那么空间至少沿着某一维完全收缩了,使其失去了所有的体积…

基于Go的语义解析开源库FMR,“屠榜”模型外的NLP利器
(由AI科技大本营付费下载自视觉中国)作者 | 刘占亮 一览群智技术副总裁编辑 | Jane出品 | AI科技大本营(ID:rgznai100)如何合理地表示语言的内在意义?这是自然语言处理业界中长久以来悬而未决的一个命题。在…

【高级数据类型2】- 10. 接口
2019独角兽企业重金招聘Python工程师标准>>> Go语言-接口 在Go语言中,一个接口类型总是代表着某一种类型(即所有实现它的类型)的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干…

Linux软件包命令
2019独角兽企业重金招聘Python工程师标准>>> dpkg命令: dpkg -i **/**.deb 安装软件 dpkg -x **.deb 解开.deb文件 dpkg -r /-p 删除并清配置 更详细的 用dpkg --help 查询 如下: dpkg -i|--install <.deb 文件的文件名> ... | -R|--re…