时隔将近两个月,我胡汉三又回来啦!!!将近两个月玩了一个月,半个月面试,半个月吃土沉淀(有收获)也投出去一篇论文(外审中,关于深度学习神经网络改进的一篇病害识别模型)。
经过了找实习工作的几场恶战:
1、测试员工程师(软件测试工程师)
2、图像算法工程师
最终发现实习其实也没有那么难找,面试了几场只噶了一场,其他都有收到offer。但是因为我是限制地区的,只找了那一个城市的工作,又限定了工作岗位,可选的没几家,好的公司也不多,毕竟大部队在暑假之后9月份吧,才真正的厮杀。
本人最终选择了相比较对口的一家公司,7月17号正式报道去实习,但是都要求长期实习,这点每个公司的同病。没有充足的时间建议不要轻试,因为现在还没入职,不知道入职后操作的难易程度,亦不知能做多久,对将来到底有没有用。(我实习的唯一目的其实是想通过实习转正,前提是得是个我满意的公司),于是乎只能去先一步入坑替大家体样一下咯,实习完了再将经验,现在问有没有必要实习?我不知道!!!
学习准备经验:
要想面试软件测试工程师的,其实不是说看一点就行,这是个什么?不就是测试吗?用不用写代码?之前一度以为很简单,也一度认为很难。这个不好好学确实不好了解,推荐一个必看的视频。
千锋软件测试必看视频
图像算法,以及视觉算法,就靠大家平时积累了,传统算法要会(opencv库),深度学习框架也要会,语言python是必须的,所有包括软件测试也要会语言,c也行,c++。这个前景还是不错的,不要听其他的,自己会的东西,工作中如鱼得水工资又高那才是最好的。
今天做了一个入职体检,抽血遇到了实习新手,最后针口青的发紫色甚至发黑(做了一次小白鼠,呜*_*)到时候还要搬着好多好多行李去往新城市。又害怕又期待,我的新篇章马上开始了!
最后,福利来了:
(吃土也不忘学习,将pyqt和之前的深度学习训练的识别模型结合起来,实现了界面化,可以当作系统了)
实现了登录、注册、主页。三个页面的灵活切换,其中主页面如下图,实现了上传原图的功能和病害识别的功能
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton,QLabel,QTextEdit,QFileDialog,QHBoxLayout,QVBoxLayout,QSplitter,QComboBox,QSpinBox
from PyQt5.Qt import QWidget, QColor,QPixmap,QIcon,QSize,QCheckBox
# 导入login.py、main.py里面全部内容
import DengLu
import my_ui
import ZuCe
import os
from PyQt5.QtCore import Qt
import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn
from nets import get_model_from_name
from utils.utils import (cvtColor, get_classes, letterbox_image,
preprocess_input, show_config)
from PIL import Image
from torchvision import transforms,models
class Classification(object):
_defaults = {
# --------------------------------------------------------------------------#
# 使用自己训练好的模型进行预测一定要修改model_path和classes_path!
# model_path指向logs文件夹下的权值文件,classes_path指向model_data下的txt
# 如果出现shape不匹配,同时要注意训练时的model_path和classes_path参数的修改
# --------------------------------------------------------------------------#
# "model_path" : 'logs/resnet_CBAM-100-best_epoch_weights-loss0.117-val_loss0.009.pth',
"model_path": 'logs/mobilenetv2-100-ep050-best-loss0.418-val_loss0.078.pth',
# 所用模型种类:
"backbone": 'mobilenetv2',
# --------------------------------------------------------------------#
# mobilenetv2、
# resnet18、resnet34、resnet50、resnet101、resnet152
# vgg11、vgg13、vgg16、vgg11_bn、vgg13_bn、vgg16_bn、
# vit_b_16、
# swin_transformer_tiny、swin_transformer_small、swin_transformer_base
"classes_path": 'model_data/cls_classes.txt',
# --------------------------------------------------------------------#
# 输入的图片大小
# --------------------------------------------------------------------#
"input_shape": [224, 224, 3],
# --------------------------------------------------------------------#
# 该变量用于控制是否使用letterbox_image对输入图像进行不失真的resize
# 否则对图像进行CenterCrop
# --------------------------------------------------------------------#
"letterbox_image": False,
# -------------------------------#
# 是否使用Cuda
# 没有GPU可以设置成False
# -------------------------------#
"cuda": True
}
@classmethod
def get_defaults(cls, n):
if n in cls._defaults:
return cls._defaults[n]
else:
return "Unrecognized attribute name '" + n + "'"
# ---------------------------------------------------#
# 初始化classification
# ---------------------------------------------------#
def __init__(self, **kwargs):
self.__dict__.update(self._defaults)
for name, value in kwargs.items():
setattr(self, name, value)
# ---------------------------------------------------#
# 获得种类
# ---------------------------------------------------#
self.class_names, self.num_classes = get_classes(self.classes_path)
self.generate()
show_config(**self._defaults)
# ---------------------------------------------------#
# 获得所有的分类
# ---------------------------------------------------#
def generate(self):
# ---------------------------------------------------#
# 载入模型与权值
# ---------------------------------------------------#
if self.backbone not in ['vit_b_16', 'swin_transformer_tiny', 'swin_transformer_small',
'swin_transformer_base']:
self.model = get_model_from_name[self.backbone](num_classes=self.num_classes, pretrained=False)
else:
self.model = get_model_from_name[self.backbone](input_shape=self.input_shape, num_classes=self.num_classes,
pretrained=False)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.model.load_state_dict(torch.load(self.model_path, map_location=device))
self.model = self.model.eval()
print('{} model, and classes loaded.'.format(self.model_path))
if self.cuda:
self.model = nn.DataParallel(self.model)
self.model = self.model.cuda()
# ---------------------------------------------------#
# 检测图片
# ---------------------------------------------------#
def detect_image(self, image):
# ---------------------------------------------------------#
# 在这里将图像转换成RGB图像,防止灰度图在预测时报错。
# 代码仅仅支持RGB图像的预测,所有其它类型的图像都会转化成RGB
# ---------------------------------------------------------#
image = cvtColor(image)
# ---------------------------------------------------#
# 对图片进行不失真的resize
# ---------------------------------------------------#
image_data = letterbox_image(image, [self.input_shape[1], self.input_shape[0]], self.letterbox_image)
# ---------------------------------------------------------#
# 归一化+添加上batch_size维度+转置
# ---------------------------------------------------------#
image_data = np.transpose(np.expand_dims(preprocess_input(np.array(image_data, np.float32)), 0), (0, 3, 1, 2))
with torch.no_grad():
photo = torch.from_numpy(image_data)
if self.cuda:
photo = photo.cuda()
# ---------------------------------------------------#
# 图片传入网络进行预测
# ---------------------------------------------------#
preds = torch.softmax(self.model(photo)[0], dim=-1).cpu().numpy()
# ---------------------------------------------------#
# 获得所属种类
# ---------------------------------------------------#
class_name = self.class_names[np.argmax(preds)]
probability = np.max(preds)
# ---------------------------------------------------#
# 绘图并写字
# ---------------------------------------------------#
plt.subplot(1, 1, 1)
plt.imshow(np.array(image))
plt.title('Class:%s Probability:%.3f' % (class_name, probability))
plt.show()
# plt.imsave(.../img,back.jpg)
img_data = np.array(image)
# 保存图像
plt.imsave('back.png', img_data)
return class_name
class my_ui(my_ui.Ui_MainWindow, QMainWindow):
def __init__(self):
super(my_ui, self).__init__()
self.setupUi(self) # 初始化
# 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
# 返回登录页slot_btn_function
self.pushButton_back.clicked.connect(self.slot_btn_function)
# 选择图片打开上传图片select_image
self.pushButton_openimg.clicked.connect(self.select_image)
# 开始识别按钮链接
self.pushButton_6.clicked.connect(self.on_btn_Recognize_Clicked2)
def slot_btn_function(self):
self.hide()
self.f = DengLu()
self.f.show()
def select_image(self):
global fname
imgName, imgType = QFileDialog.getOpenFileName(self, "打开图片", "", "*.png;;*.jpg;;All Files(*)")
jpg = QtGui.QPixmap(imgName).scaled(self.label.width(), self.label.height())
# jpg = QtGui.QPixmap(imgName)
self.label.setPixmap(jpg)
fname = imgName
print(fname)
def on_btn_Recognize_Clicked2(self):
classfication = Classification()
while True:
global fname
# savePath = fname
img = os.path.abspath(fname)
print("图像的绝对路径:",img)
# img = input('Input image filename:')
try:
image = Image.open(img)
except:
print('Open Error! Try again!')
self.textBrowser.setText("请先上传待测图片!")
continue
else:
class_name = classfication.detect_image(image)
print("识别结果为:" + class_name)
if class_name == "rot":
class_name = "褐腐病\r\n灰斑病常发病于秋季,初期病斑呈黄褐色圆形状且边缘清晰,病后期病斑区域不断扩大呈现不规则状,病斑区域密集相连加快叶片枯萎。"
elif class_name == "scab":
class_name = "黑星病黑\r\n星病病斑初期呈淡黄色圆形或放射状,逐渐变为棕色,最终变为黑色,病叶上常有多个斑点相互融合,病部干枯开裂,叶柄上的病斑通常是长条状的。"
elif class_name == "rust":
class_name = "雪松锈病\r\n雪松锈病初期病斑呈明亮的桔红色,随后为圆型,边缘为红色病斑呈橙色;患病后期,叶片上病斑逐渐增多,表面呈现密集的小颗粒黄色状病斑。"
self.textBrowser.setText("识别结果为:" + class_name)
# break跳出循环
break
# self.edit.setText('识别结果为:' str(txt))
class DengLu(DengLu.Ui_Form, QMainWindow):
def __init__(self):
super(DengLu, self).__init__()
self.setupUi(self)
# 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
'''定义跳转到主页按钮'''
self.btn_login.clicked.connect(self.tiaozhuanzhuye)
'''定义跳转到注册页按钮'''
self.btn_login_zuce.clicked.connect(self.tiaozhuanzuce)
def tiaozhuanzhuye(self):
self.hide()
self.f = my_ui()
self.f.show()
def tiaozhuanzuce(self):
self.hide()
self.f = Ui_ZuCe()
self.f.show()
class Ui_ZuCe(ZuCe.Ui_Form, QMainWindow):
def __init__(self):
super(Ui_ZuCe, self).__init__()
self.setupUi(self)
# 每写一个按钮链接对应的让它做啥可以在下面添加一个函数
self.btn_back.clicked.connect(self.slot_btn_function)
def slot_btn_function(self):
self.hide()
self.f = DengLu()
self.f.show()
if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # 支持高分屏自动缩放
app = QApplication(sys.argv)
# 为my_ui_window类和login_window类创建对象
# main_window = main()
login_window = DengLu()
classification = Classification()
zuce_window = Ui_ZuCe()
my_ui_window = my_ui()
# 显示登陆窗口
login_window.show()
# 关闭程序,释放资源
sys.exit(app.exec_())