内核中读写文件
公司专注于为企业提供网站制作、成都网站设计、微信公众号开发、商城网站制作,成都小程序开发,软件定制网站设计等一站式互联网企业服务。凭借多年丰富的经验,我们会仔细了解各客户的需求而做出多方面的分析、设计、整合,为客户设计出具风格及创意性的商业解决方案,成都创新互联更提供一系列网站制作和网站推广的服务。
1.filp_open()在kernel中可以打开文件,其原形如下:
Struct file* filp_open(const char* filename, int open_mode, int mode); 该函数返回strcut file*结构指针,供后继函数操作使用,该返回值用IS_ERR()来检验其有效性。
2. 读写文件(vfs_read/vfs_write)
kernel中文件的读写操作可以使用vfs_read()和vfs_write,在使用这两个函数前需要说明一下get_fs()和 set_fs()这两个函数。
vfs_read() vfs_write()两函数的原形如下:
ssize_t vfs_read(struct file* filp, char __user* buffer, size_t len, loff_t* pos);
ssize_t vfs_write(struct file* filp, const char __user* buffer, size_t len, loff_t* pos);
注意这两个函数的第二个参数buffer,前面都有__user修饰符,这就要求这两个buffer指针都应该指向用空的内存,如果对该参数传递kernel空间的指针,这两个函数都会返回失败-EFAULT。但在Kernel中,我们一般不容易生成用户空间的指针,或者不方便独立使用用户空间内存。要使这两个读写函数使用kernel空间的buffer指针也能正确工作,需要使用set_fs()函数或宏(set_fs()可能是宏定义),如果为函数,其原形如下:
void set_fs(mm_segment_t fs);
该函数的作用是改变kernel对内存地址检查的处理方式,其实该函数的参数fs只有两个取值:USER_DS,KERNEL_DS,分别代表用户空间和内核空间,默认情况下,kernel取值为USER_DS,即对用户空间地址检查并做变换。那么要在这种对内存地址做检查变换的函数中使用内核空间地址,就需要使用set_fs(KERNEL_DS)进行设置。get_fs()一般也可能是宏定义,它的作用是取得当前的设置,这两个函数的一般用法为:
Mat类:
是用于保存图像以及其他矩阵数据的数据结构。
图像载入函数imread():
Mat imread(const string filename, int flags=1);
filename表示图像载入的路径;
flags为载入标识。
flags=0 将图像转换为灰度再返回;
flags=1 将图像转换成彩色再返回;
flags=2 若载入图像的深度是16位或者32位,就返回对应的图像深度,否则,将图像转换为8位图像再返回。
flags=2|4 载入最真实无损的源图像
若flags不在枚举类型当中,flags0 返回一个三通道的彩色图像;flags=0 返回灰度图像;flags0 返回包含Alpha通道的加载图像。
图像显示函数imshow():
void imshow(const string winname, InputArray mat);
winname填写要显示的窗口标识名称;
mat填需要显示的图像。
输出图像到文件imwrite():
bool imwrite(const string filename, InputArray img, const vector params=vector());
第一个参数filename表示要写入的文件名
第二个参数img表示Mat类型的图像数据
通道分离split()函数;
void split(const Mat src, Mat* mvbegin);
void split(InputArray m, OutputArrayofArray mv);
第一个参数表示需要进行分离的多通道数组;
第二个参数表示函数 输出数组或输出的vector容器。
通道合并merge()函数:
void merge(const Mat* mv, size_t count, OutputArray dst)
void merge(InputArrayOfArray mv, OutputArray dst);
第一个参数mv表示需要被合并的输入矩阵或vector容器的阵列,mv参数中所有矩阵必须拥有一样的尺寸;
第二个参数count表示当mv为空白的C数组时,代表输入矩阵的个数,通常可以省略不写;
第三个参数dst表示输出矩阵,和mv拥有一样的尺寸和深度
Python与OpenCV图像简单操作
文章目录
OpenCV安装
1.读取图片
2.保存图片
3.截取部分图像
4.图片翻转
5.缩放图片
6.转换为灰度图像
7.在一个窗口中显示两张图片
8.绘图功能
OpenCV安装
打开命令行输入 pip install opencv-python(前提是有python环境)
1.读取图片
使用 cv2.imread() 函数,给出了几种读取图片路径的写法
import cv2#导入opencv包
#python中不需要声明变量
img1 = cv2.imread("D:/test/1.jpg")#绝对路径,推荐
img2 = cv2.imread("D:\\test\\2.jpg")#通常是两个斜线,单右斜线会被当成转义符
img3 = cv2.imread("3.jpeg")#相对路径,将图片放在py文件对应目录下
cv2.imshow("test1", img1)
cv2.imshow("test2", img2)
cv2.imshow("test3", img3)
cv2.waitKey(0)#没有这一句图片会一闪而过
##waitkey(delay=0),等待用户输入按键,返回该按键的值
2.保存图片
使用 cv2.write() 函数保存图片
import cv2# 导入OpenCV包
img=cv2.imread("D:/test/3.png",cv2.IMREAD_COLOR)
cv2.imshow("test",img)#OpenCV可以实现不同格式图片转换,支持jpg、bmp、png等图片格式相互无损转换
cv2.imwrite("D:/test/3.1.png",img)#将改变后的图像保存
cv2.imwrite("D:/test/3.2.bmp",img)
cv2.waitKey(0)
3.截取部分图像
import cv2
img = cv2.imread("D:\\test\\2.jpg")
frame = img[200:400,200:400] #截取部分图像,200-400行,200-400列
cv2.imshow("test",frame)#显示截取后的图像
cv2.waitKey(0)
4.图片翻转
使用cv2.flip(img,flipcode)来进行图片翻转
flipcode控制图片翻转方向
import cv2
img=cv2.imread("D:/test/5.jpg",cv2.IMREAD_COLOR)
flipCode1=1#大于0左右翻转
flipCode2=0#等于0上下翻转
flipCode3=-1#小于0先上下翻转再左右翻转
img1 = cv2.flip(img, flipCode1)#filpCode控制图片翻转方向
img2 = cv2.flip(img, flipCode2)
img3 = cv2.flip(img, flipCode3)
cv2.imshow("test",img)
cv2.imshow("test1",img1)
cv2.imshow("test2",img2)
cv2.imshow("test3",img3)
cv2.waitKey(0)
5.缩放图片
cv2.resize(img,dsize,fx,fy),dsize和fx,fy都可以设置图片大小,不能同时为0
import cv2# 导入OpenCV包
img = cv2.imread("D:/test/2.jpg",cv2.IMREAD_COLOR)
img1 = cv2.resize(img, (700, 700))#设置输出图片的尺寸
img2 = cv2.resize(img, None, fx=0.7, fy=0.7)#None的位置本来是输出图片的尺寸,这里设置了缩放因子
#fx-水平轴上的比例因子,fy-垂直轴上的比例因子
cv2.imshow("test", img)
cv2.imshow("test1", img1)
cv2.imshow("test2", img2)
cv2.imwrite("D:/test/resize.jpg", img1)# 保存图像
cv2.waitKey(0)
6.转换为灰度图像
cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
cv2.COLOR_RGB2GRAY表示把RGB图像转为灰度图像,2前是转换前,2后是转换后
import cv2#导入opencv包
#python中不需要声明变量
img = cv2.imread("D:/test/1.jpg")#cv2.imread读进来的图片格式是BGR(W,H,C),而不是RGB
cv2.imshow("BGR", img)
#将图像转换为RGB格式
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#因为opencv读取图片是按BGR读的,所以转换为RGB反而不像原图
cv2.imshow("RGB",img1)
#将图像转换为灰度图像
img2 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
cv2.imshow("GRAY",img2)
cv2.waitKey(0)
7.在一个窗口中显示两张图片
import cv2
import numpy as np
img = cv2.imread("D:/test/resize.jpg")
img2 = cv2.imread("D:/test/resize.jpg")
#imgs = np.hstack([img,img2])#在水平方向上平铺
imgs = np.vstack([img,img2])#在竖直方向上堆叠
cv2.imshow("mutil_pic", imgs)
cv2.waitKey(0)
8.绘图功能
import cv2
import numpy as np
img = 255*np.ones((350,512,3),np.uint8)#unit8:0~255
#ones()为创建一个元素均为一的矩阵
font = cv2.FONT_HERSHEY_DUPLEX
#font = cv2.FONT_HERSHEY_COMPLEX# 设置字体
#文本 # 图片对象、文本、 位置、 字体、字体大小、颜色、 字体粗细
cv2.putText(img, "happy day", (50,300), font, 0.8, (25, 25, 25), 2,)#颜色可以自己调整,范围为0-255
#线 #起点 终点 颜色 粗细
cv2.line(img, (50,310), (185,310), (0, 0,0),4)
#矩形 #左上顶点 右下顶点
cv2.rectangle(img, (80,8), (200,100), (0, 255,0),2)
#圆形 #圆心 半径 颜色 控制是否填充 -1表示填充
cv2.circle(img,(60,60),30,(0,0,213),1)
#椭圆 #中心点 长轴 短轴 偏转角度,起始角度,终止角度
cv2.ellipse(img,(100,300),(100,50),180,0,360,(20,213,79),1)
cv2.imshow("Draw", img)
cv2.waitKey(0)
1.np.vstack([img1,img2]) 当img1和img2图片矩阵维度相同时才能堆叠
2.除了imread,imwrite 函数没有返回值以外,flip,resize,cvtColor,vstack,hstack都有返回一个图片回来。
这是一个文件读函数
我们很容易看出输入参数中
filp 是文件
buf 是文件要读到什么地方去,用户buf
count是要读多少东西
那么ppos是什么东东,是当前文件的偏移量嘛??
但是当前文件的偏移量在filp中有定义呀。struct file {
struct list_head f_list;
struct dentry *f_dentry;
struct vfsmount *f_vfsmnt;
struct file_operations *f_op;
atomic_t f_count;
unsigned int f_flags;
mode_t f_mode;
loff_t f_pos;//这个就是当前文件的偏移量,我认为struct file 中的f_pos是最后一次文件操作以后的当前读写位置。而ppos是这次对文件进行操作的起始位置,这两个值不一定相等。
# 标有"#"的行是修改过的,对比一下看看。
class LightSwitch:
def __init__(self,condition):
self.is_on = condition
if not isinstance(condition,bool):
InvaildSwitchExpection = TypeError("it is not a right state".format(condition))
raise InvaildSwitchExpection
def turn_on(self):
self.is_on = True
def turn_off(self):
self.is_on = False
def filp(self):
if self.is_on == False:
self.is_on = True
else:
self.is_on = False
def __str__(self):
if self.is_on == True:
return "I am on"
else:
return "I am off"
class SwitchBoard(LightSwitch):
def __init__(self, number):
self._lights = []
for i in range(0, number):
i = LightSwitch(False)
self._lights.append(i)
def which_switch(self):
result = []
for i in range(0, len(self._lights)):
if self._lights[i].is_on == True:
result.append(str(i)) #
return result
def __str__(self):
result = self.which_switch() #
result_str = ','.join(result)
return 'The following switches are on: ' + result_str
def filp(self, n):
if self._lights[n] == False:
self._lights[n].is_on = True
else:
self._lights[n].is_on = False
def filp_every(self, n):
k = 0
while n * k = len(self._lights) - 1:
if self._lights[n * k].is_on == False:
self._lights[n * k].is_on = True
else:
self._lights[n * k].is_on = False
k = k + 1
def reset(self):
for light in self._lights:
light.is_on = False #
light_board = SwitchBoard(10)
print(light_board)
light_board.filp_every(2)
print(light_board)
light_board.filp(2)
print(light_board)
light_board.reset()
print(light_board)
light_board.filp_every(1)
print(light_board)
有的代码可以写得更简洁,基类已经提供的服务(接口),在派生类中直接使用就可以了。下面的仅供参考。
class LightSwitch:
def __init__(self,condition):
self.is_on = condition
if not isinstance(condition,bool):
InvaildSwitchExpection = TypeError("it is not a right state".format(condition))
raise InvaildSwitchExpection
def turn_on(self):
self.is_on = True
def turn_off(self):
self.is_on = False
def filp(self):
self.is_on = not self.is_on ##
def __str__(self):
if self.is_on == True:
return "I am on"
else:
return "I am off"
class SwitchBoard(LightSwitch):
def __init__(self, number):
self._lights = []
for i in range(number):
i = LightSwitch(False)
self._lights.append(i)
def which_switch(self):
result = []
for i in range(len(self._lights)): ##
if self._lights[i].is_on == True:
result.append(str(i)) #
return result
def __str__(self):
result = self.which_switch() #
result_str = ','.join(result)
return 'The following switches are on: ' + result_str
def filp(self, n):
self._lights[n].filp() ##
def filp_every(self, n):
k = 0
while n * k = len(self._lights) - 1:
self.filp(n * k) ##
k = k + 1
def reset(self):
for light in self._lights:
light.turn_off() ##
light_board = SwitchBoard(10)
print(light_board)
light_board.filp_every(2)
print(light_board)
light_board.filp(2)
print(light_board)
light_board.reset()
print(light_board)
light_board.filp_every(1)
print(light_board)