openCV实践项目:银行卡卡号识别

本文用于对之前openCV知识点学习的复习及实践。要求达到以下效果:

一、基本流程思路分析

本项目本质上就是进行模板匹配。

注:为多用到所学知识,为了加深理解多加了些步骤,实际上本项目可以很简单就能完成。

1.1 模板处理 

模板:

  1. 转换成灰度图,二值化处理,用于轮廓检测。 
  2. 我们将模板中的十个数字通过轮廓检测(外轮廓),能够获得每个数字拐点处的坐标。
  3. 将这些返回值对其使用外接矩形,我们能得到每个数字的外接矩形的(x,y,h,w),上图是从左到右从小到大排列的,我们只需根据x的大小进行正向排序即可。
  4. 循环遍历通过切片切出外接矩形,保存到字典中,对应0-9。

实际上:第二步我们可以直接将返回值倒序,得到对应0-9的正向拐点坐标列表,对其直接外接矩形切片即可。

1.2 银行卡处理

银行卡中呢有很多的干扰项,或者说是没用的地方,因为我们需要的只是中间的那一块数字。我们不直接选中的话,思路如下:

  1. 将其转换为灰度图。
  2. 礼帽操作(原始图像-开运算后的图像),目的是突出更明亮的地方,不明白没关系最后会有总结。
  3. 梯度处理,归一化。礼帽操作本次实验中去掉了背景部分,方便梯度处理对其进行差异描绘,更干净些。
  4. 对梯度处理后的图像进行闭操作,此时如上图4000、1234、5678、9010这四块都连在一起是一个整体了。
  5. 进行二值处理,用于后面轮廓检测,把那四块数字的轮廓检测出来。
  6. 进行闭操作,原理同4。
  7. 轮廓检测,我们所需要的这四段数字它们的外接矩形的长宽或者比例是与途中其它元素不同的,我们通过这一特征在轮廓检测返回的队列中筛选出需要的部分,保存下来。
  8. 同样,根据x坐标的位置进行排序。
  9. 有了这4段外接矩形的坐标,我们可以在原图片上把它们抠出来(切片)。
  10. 对每一组进行轮廓检测、排序(倒序),得到单个数字的轮廓,继续对其外接矩形切片。
  11. 得到的每个数字的外接矩形矩阵,与模板中每个数字进行匹配,得分最高对应正确数字。

注:上述过程有很大优化的空间,这样做是为了加深理解,具体可看代码部分。

二、主要知识点罗列

图片读取、转换为灰度图、滤波操作等

略 

二值处理

ret, dst = cv2.threshold(src, thresh, maxval, type)

  • ret, dst: 返回阈值、输出图。

  • src: 输入图,只能输入单通道图像,通常来说为灰度图。

  • thresh: 阈值。

  • maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值。

  • type:二值化操作的类型,包含以下5种类型: 

    • cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0

    • cv2.THRESH_BINARY_INV , THRESH_BINARY的反转

    • cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变

    • cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0

    • cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转

计算轮廓

cv2.findContours(img,mode,method) 

  • RETR_EXTERNAL :只检索最外面的轮廓;( 本次使用)
  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;(常用,推荐)

method:轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。

绘制轮廓

cv2.drawContours(draw_img, refCnts, -1, (0, 0, 255), 2)

  • draw_img:要绘制的图片,会在该图片上直接进行修改。
  • refCnts: 轮廓
  • 其它:-1指全部轮廓,0为最后一个轮廓,(0,0,255)颜色,2粗细。

排序

refCnts = contours.sort_contours(refCnts, method="left-to-right")[0]

  • 返回排序后的轮廓。

礼帽操作

tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)

  • 原图-开运算,本次实验用它获得我们想要保留的部分。
  • 开运算:先腐蚀后膨胀。

闭运算

gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)

  • 先膨胀后腐蚀,本次实验目的是将每组数“模糊处理”使其连在一起。

模板匹配

res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)

  • 模板匹配和卷积原理很像,假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)。
  • TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
  • TM_CCORR:计算相关性,计算出来的值越大,越相关
  • TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
  • TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
  • TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
  • TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

  •  最小值最大值及其坐标位置,具体看模板匹配使用的方法是什么。

更多初级知识点:

openCV第三篇_老师我作业忘带了的博客-CSDN博客

三、代码部分

3.1 代码讲解 

3.1.1 处理模板 

  • 导包
import cv2
import numpy as np
from imutils import contours # 排序操作,也可以不用。
  • 定义绘图展示函数
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0) # 按键结束cv2.destroyAllWindows()

  • 模板读取、灰度、二值化 
# 读取模板图像
img = cv2.imread('ocr_a_reference.png')# 转换为灰度图 也可读取时直接转换
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 二值图像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]

  • 轮廓检测、排序
# 轮廓检测
refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
'''
draw_img = img.copy()
cv2.drawContours(draw_img, refCnts, -1, (0, 0, 255), 2) # 第0个轮廓是9 第1个轮廓是8......
cv_show('draw_img',draw_img)
'''# 排序(倒序操作) 得到正序0-9的轮廓
refCnts = sorted(refCnts,key=lambda b: b[0][0][0], reverse=False)

  • 遍历对这10个轮廓,做外接矩形,对外接矩形区域在二值化图ref上做切片,即把他们一个个抠出来,保存在 digits 字典中。
digits = {}# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):# 计算外接矩形并且resize成合适大小(x, y, w, h) = cv2.boundingRect(c)roi = ref[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# 每一个数字对应每一个模板,此时模板中的10个数字分别被保存到了字典中digits[i] = roi

3.1.2 处理银行卡

  • 初始化卷积核,读取输入图像。
# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 读入银行卡
image = cv2.imread('./images/credit_card_01.png')

  • 统一大小,这里建议让它变小一点,处理像素少一点,后面闭运算让其模糊也方便一些。
set_width = 300 # 自己设定 这里我统一了宽度
rate = set_width/image.shape[:2][1]
image = cv2.resize(image,(0,0),fx=rate,fy=rate)
  • 转为灰度图
# 同样也可以在第一步完成
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

  • 礼帽,突出更明亮的区域,可以看到此时银行卡后面的花纹基本已经消失了。 。
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)

  • 梯度运算,这里使用Sobel算子,只进行了x方向计算。前面的礼帽操作是的我们梯度运算结果更干净些。
# ksize=-1相当于用3*3的
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradX = np.absolute(gradX) # 绝对值,白-黑 黑-白
# 或者写为 cv2.convertScaleAbs(sobelx)# 归一化处理
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
# gradX与最小值之间的距离占区间长度的几分之几
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))  
gradX = gradX.astype("uint8")

  • 闭运算、二值化、闭运算
# 闭运算 把银行卡卡号那里弄模糊
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)# 二值化,用于之后轮廓检测。
thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 再来一个闭操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)  

  • 轮廓检测
threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
'''
cur_img = image.copy()
cv2.drawContours(cur_img, threshCnts, -1, (0, 0, 255), 3)
cv_show('img', cur_img)
'''

  • 遍历所有轮廓,得到想要的四组数字,并排序。
locs = []# 遍历轮廓
for (i, c) in enumerate(threshCnts):# 计算矩形(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组if ar > 2.5 and ar < 4.0:if (w > 40 and w < 55) and (h > 10 and h < 20):# 符合的留下来locs.append((x, y, w, h))# 将符合的这四组轮廓按x从左到右排序
locs = sorted(locs, key=lambda x: x[0])
  • 遍历这四组数
output = []# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):groupOutput = []# 根据坐标提取每一个组group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]cv_show('group', group)# 预处理group = cv2.threshold(group, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show('group', group)# 计算每一组的轮廓# group_, digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 就是个排序 真正的顺序我们都知道,可以自己用sort函数digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]# 计算每一组中的每一个数值for c in digitCnts:# 找到当前数值的轮廓,resize成合适的的大小(x, y, w, h) = cv2.boundingRect(c)roi = group[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))cv_show('roi', roi)# 计算匹配得分scores = []# 在模板中计算每一个得分  字典digits记录了模板0-9for (digit, digitROI) in digits.items():# 模板匹配result = cv2.matchTemplate(roi, digitROI,cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)# 得到最合适的数字,这里用的匹配方法对应得分越大越好。groupOutput.append(str(np.argmax(scores)))# 画出来cv2.rectangle(image, (gX - 5, gY - 5),(gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)cv2.putText(image, "".join(groupOutput), (gX, gY - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 得到结果output.extend(groupOutput)

  • 输出结果
print("Credit Card #: {}".format("".join(output)))
# cv_show("Image", image)
Credit Card #: 4000123456789010

3.2 完整代码  直接copy

我去掉了图片展示,直接输出文本结果。 

import cv2
import numpy as np
from imutils import contours  # 排序操作,也可以不用。# 绘图展示
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()# 读取一个模板图像
img = cv2.imread('ocr_a_reference.png', )
# 灰度图
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值图像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]# 轮廓检测
refCnts, hierarchy = cv2.findContours(ref, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 排序(倒序操作) 得到正序0-9的轮廓
refCnts = sorted(refCnts, key=lambda b: b[0][0][0], reverse=False)digits = {}
# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):# 计算外接矩形并且resize成合适大小(x, y, w, h) = cv2.boundingRect(c)roi = ref[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# 每一个数字对应每一个模板,此时模板中的10个数字分别被保存到了字典中digits[i] = roi# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 读入银行卡
image = cv2.imread('./images/credit_card_01.png')# 统一大小,这里建议让它变小一点,处理像素少一点,后面闭运算让其模糊也方便一些。
set_width = 300  # 自己设定 这里我统一了宽度
rate = set_width / image.shape[:2][1]
image = cv2.resize(image, (0, 0), fx=rate, fy=rate)# 转为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 礼帽,突出更明亮的区域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)# 梯度运算,这里使用Sobel算子,只进行了x方向计算。前面的礼帽操作是的我们梯度运算结果更干净些。
# ksize=-1相当于用3*3的
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradX = np.absolute(gradX)  # 绝对值,白-黑 黑-白
# 或者写为 cv2.convertScaleAbs(sobelx)# 归一化处理
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
# gradX与最小值之间的距离占区间长度的几分之几
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")# 闭运算 把银行卡卡号那里弄模糊
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
# 二值化,用于之后轮廓检测。
thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 再来一个闭操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)# 轮廓检测
threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)locs = []
# 遍历轮廓
for (i, c) in enumerate(threshCnts):# 计算矩形(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组if ar > 2.5 and ar < 4.0:if (w > 40 and w < 55) and (h > 10 and h < 20):# 符合的留下来locs.append((x, y, w, h))# 将符合的这四组轮廓按x从左到右排序
locs = sorted(locs, key=lambda x: x[0])# 遍历这四组数
output = []# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):groupOutput = []# 根据坐标提取每一个组group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]# 预处理group = cv2.threshold(group, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 计算每一组的轮廓# group_,digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 就是个排序 真正的顺序我们都知道,可以自己用sort函数digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]# 计算每一组中的每一个数值for c in digitCnts:# 找到当前数值的轮廓,resize成合适的的大小(x, y, w, h) = cv2.boundingRect(c)roi = group[y:y + h, x:x + w]roi = cv2.resize(roi, (57, 88))# 计算匹配得分scores = []# 在模板中计算每一个得分  字典digits记录了模板0-9for (digit, digitROI) in digits.items():# 模板匹配result = cv2.matchTemplate(roi, digitROI,cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)# 得到最合适的数字,这里用的匹配方法对应得分越大越好。groupOutput.append(str(np.argmax(scores)))# 画出来cv2.rectangle(image, (gX - 5, gY - 5),(gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)cv2.putText(image, "".join(groupOutput), (gX, gY - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 得到结果output.extend(groupOutput)print("Credit Card #: {}".format("".join(output)))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/61389.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是物联网平台

1、什么是物联网平台 阿里云物联网平台为设备提供安全可靠的连接通信能力&#xff0c;向下连接海量设备&#xff0c;支撑设备数据采集上云&#xff1b;向上提供云端API&#xff0c;服务端通过调用云端API将指令下发至设备端&#xff0c;实现远程控制。 物联网平台消息通信流程…

新兴 IoT 物联网场景中 MQTT 与 TCP 通信协议对比

在IoT 物联网开发中&#xff0c;大多数通信模组都支持 TCP、UDP、MQTT、CoAP、HTTP、LwM2M 等网络通信协议&#xff0c;其中既有传输层协议&#xff0c;也有应用层的协议&#xff0c;不同协议适用的场景也不同。 我们在设计IoT硬件产品时&#xff0c;通常只需选择一种协议即可。…

lot物联网场景通用架构分享

1.通用参考架构&#xff1a; 2.lot物联网硬件设备上云技术方案&#xff1a; #lot物联网业务链路包含&#xff1a;数据采集&#xff0c;通信连接&#xff0c;数据存储&#xff0c;数据可视化&#xff0c;洞察&#xff0c;行动决策&#xff1b;其中以设备端各种厂商提供得协议差…

物联网网络通讯知识

RTU是什么 RTU英文全称Remote Terminal Units&#xff0c;中文全称为远程终端单元。远程终端设备(RTU)是安装在远程现场的电子设备&#xff0c;用来监视和测量安装在远程现场的传感器和设备。通俗理解就是能够编程的还可以将数据传输到服务器的工具。RTU内部是包含通讯模块的&…

APP与服务器之间通过 http(POST、GET)进行数据交互 ( 实现一个简单的物联网系统-1 )

文章目录 一、APP POST 数据到服务器二、APP 从服务器 GET 数据三、APP 界面部分四、相关疑问五、学习方法六、专栏地址 一、APP POST 数据到服务器 首先 post 的数据应该包括识别这个花卉的信息和我们想要浇水的量&#xff0c;这里我们识别花卉采用花卉的名字&#xff0c;这样…

什么是物联网(Internet of Things)?

你可能在某些时候会听到物联网这个词&#xff0c;但是你对它可能不知所以然&#xff0c;这篇文章让你弄清楚什么是物联网&#xff0c;以及它代表什么&#xff1f; 物联网&#xff08;Internet of Things&#xff09;是指设备到互联网的连接。汽车&#xff0c;厨房电器&#xff…

物联网网关有哪些能力和哪些应用?

工业物联网的应用受到越来越多企业的关注&#xff0c;很多人都了解网关这个概念。网关就是一个网络连接到另一个网口的桥梁&#xff0c;起到协议解析、数据采集的作用&#xff0c;实现运行状态数据的高效利用。 物联网网关具备的能力 1、广泛连接的能力 目前各个行业、不同设…

一文了解物联网网关

物联网是指通过射频识别(RFID)、红外感应器、GPS、激光扫描器等信息传感设备&#xff0c;按约定的协议&#xff0c;实现任何时间、任何地点、任何物体进行信息交换和通信&#xff0c;以实现智能化识别、定位、监控和管理的一种网络。物联网是具有全面感知、可靠传输、智能处理特…

什么是物联网?有哪些应用?终于有人讲明白了

作者&#xff1a;佩里利&#xff08;Perry Lea&#xff09; 来源&#xff1a;大数据DT&#xff08;ID&#xff1a;hzdashuju&#xff09; 我们将从连接设备的角度来研究物联网&#xff0c;这些设备之前未必相互连接或接入互联网。它们可能一直没有太多的计算或通信能力。我们假…

LPWA物联网通信

物联网LPWA是物联网中的无线通信技术之一。 根据物联网无线通信技术的覆盖距离&#xff0c;大致可分为两类&#xff1a;一类是短距离通信技术&#xff0c;包括蓝牙(蓝牙)&#xff1b;NFC,Zigbee、WIFI、NFC&#xff0c;主要用于室内智能家庭、消费电子等场景&#xff1b;另一种…

物联网通讯协议:MQTT,NB-IOT,Zigbee,CoAP,RFID,BLUETOOTH,NFC,4G,HTTP

目录 一、按网络四层协议分类二、按需要网关来分类三、NB-IoT&#xff0c;4G对比四、应用层协议&#xff1a;MQTT和COAP对比物联网组网技术WIFI蓝牙ZigBee2G/4G/5GNB-IoTLoRa网关 物联网中常见的物联通信协议TCPUDPTCP和UDP比较HTTPMQTTCoAPLwM2M 一、按网络四层协议分类 NB-I…

chatgpt赋能python:如何使用Python拷贝微信聊天记录的图片?

如何使用Python拷贝微信聊天记录的图片&#xff1f; 微信聊天记录中的图片是我们很重要的一部分。它们记录了我们和我们的朋友、家人和同事之间的重要时刻和特殊瞬间。然而&#xff0c;有些时候我们需要把这些图片从微信聊天记录中拷贝出来&#xff0c;以便于备份和共享。本文…

《辉煌优配》科技股强势引领A股反弹 沪深两市日成交额再超万亿元

受美联储再度加息扰动&#xff0c;昨日早盘沪深两市指数低开&#xff0c;随后科技股强势拉升&#xff0c;带动商场回暖。到收盘&#xff0c;上证综指报3286.65点&#xff0c;上涨0.64%&#xff1b;深证成指报11605.29点&#xff0c;上涨0.94%&#xff1b;创业板指报2361.41点&a…

深度分析台积电的投资价值:伟大的公司,伟大的投资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 公司介绍 台积电&#xff08;TSM&#xff09;是一家在1987年成立于台湾的半导体公司&#xff0c;并在全球范围内率先实施了“商业晶圆厂”代工模式。该公司为部分或全部外包生产的半导体生产商提供晶圆代工服务。台积电的产…

汇正财经靠谱吗?沪深创再现调整

盘面回顾&#xff1a; 周三A股开盘时间段&#xff0c;人民币再现快速贬值&#xff0c;再加上5月PMI数据不及预期&#xff0c;空头情绪放大&#xff0c;沪深创再陷调整&#xff0c;截止收盘沪指跌0.61%&#xff0c;深成指跌0.7%&#xff0c;创业板指跌1.14%。全天唯独科创50能逆…

超级模型GPT-4发布!

本文来源 量子位 一觉醒来&#xff0c;万众期待的GPT-4&#xff0c;它来了&#xff01; OpenAI老板Sam Altman直接开门见山地介绍说&#xff1a; 这是我们迄今为止功能最强大的模型&#xff01; 有多强&#xff1f; 根据OpenAI官方的介绍&#xff0c;GPT-4是一个超大的多模态…

透过现象看本质 | GPT爆火的背后

前言&#xff1a; 近年来&#xff0c;GPT&#xff08;Generative Pre-trained Transformer&#xff09;作为一种革命性的语言模型&#xff0c;以其强大的文本生成能力和广泛的应用领域引发了全球范围内的热议。然而&#xff0c;GPT爆火的背后&#xff0c;是一个更加深刻的本质。…

2014年考研英语二作文PartB图表题

作文详细解析 题目 Write an essay based on the following chart, in which you should interpret the chart, and give your comments You should write about 150 words on the ANSWER SHEET.(15 points) 注意点 1.图表题在第一段描述图表信息时,一定要写清楚y轴变化…

【考研】2018-Part B 作文(英一)

前言 10月要开始冲刺英一作文&#xff0c;会陆续推出 2013 - 2022 英一 Part A 和 PartB 的优秀范文&#xff0c;并用红色字体标明应用模板&#xff0c;并列举重点单词和词组&#xff0c;以积累词汇。 一、2018 Part B &#xff08;一&#xff09;题目及解析 提示信息信息解析…

python代码打包成可执行文件(exe)

【前言】&#xff1a;我们在开发完一个小项目后&#xff0c;想要把项目发布出来给别人用。通常都会把代码打包成exe后再给别人&#xff0c;而不是让别人去安装运行环境再跑裸代码。本文就是介绍如何使用pyinstaller这个工具将python带包成可直接运行的exe。 ▍概述 在介绍pyi…