其实很早之前就想整理一下自己几个月前的工作日志了。因为种种原因,我可能不会再往IC测试验证这方向走了,哈哈,套用游戏里面一句自嘲的话,那就是“菜是原罪”。当然还有其他主观性的原因,我这个人向来不喜欢倾诉苦水,那些就暂且不聊,说回正题。
刚来到Hynitr(手动打码)的时候,还是一名小白(当然现在也还是),那时候刚进去,难以掩饰的兴奋好奇,这里一切都是新鲜事物。以及一丝丝的忐忑,忐忑是因为啥也不懂,啥也不会,害怕会被责骂(现在看来,其实还是很感谢Hynitr的,包容了一无所有、一无所知的我们,几个月下来给公司带来的收益几乎为0,但领导似乎并没有责怪我们,相反还给了我们鼓励,这也正是我继续留在微电子这个行业的动力,待我出走十年,定要立足一方天地,适时再与昔日的德哥说说世事沧桑)。
回到正题,因为种种原因,我们并没有被分到与我们专业相关度更高的设计部(模拟设计部、数字系统部、CAD部、版图设计部),相反来到了系统应用部,这个部门的主要职责就是负责芯片的后端,比如说固件、验证测试等等。这其实和单片机以及嵌入式联系比较紧密,但整个大学四年(准确来说应该是三年,因为当时我们还是大四上,疫情又耽误了一整个学年,所以整个加起来其实也就两年)我们对计算机语言和软件方面学得并不多,因为并没有打算往CS方向走,单片机也是浅尝而止,所以可以说零基础入职。
邮件里面的工作安排也只是简短几句话,但对于我和我的小伙伴来说是比较困难的。我们必须硬着头皮干,于是我们风风火火的开始了,先是搭建环境,其他的环境就不多描述了,这里只是想简单记录一下 QT的一些代码,因为这些都是我们的心血啊,真就一个代码一个代码自己敲进去的,尤其是触碰到迷宫算法的时候,网上大牛的迷宫算法虽然和我们原理相通,但不是我们要的效果,我们不是要走迷宫走出来,而是要无限地走迷宫,就是走一个没有出口的数字迷宫,(反正那两个星期真是头皮发麻,再次佩服写出原芯片功能的大佬,几千行的代码,每一个功能环环相扣,且平滑细腻),那时候一天看N多视频,然后一个一个的分析原理,再根据要实现的功能自己写,耗费诸多心血,当然做出来的效果依旧差强人意。不过那也是我花费了很多精力做出来的,虽然以后可能不会再往这个方向走了,但还是想记录一下。
头文件.h
#ifndef TEST3_30_H
#define TEST3_30_H
#include <QMainWindow>
struct spot
{
int _x;
int _y;
};
QT_BEGIN_NAMESPACE
namespace Ui { class test3_30; }
QT_END_NAMESPACE
class test3_30 : public QMainWindow
{
Q_OBJECT
public:
test3_30(QWidget *parent = nullptr);
~test3_30();
int nextframe(bool checked = false);
int lastframe(bool checked = false);
void openfile(QString filepath, int frame_idx);
int nowframe;
QString filepath;
int march[250][4]={0,0,0,0};
private:
Ui::test3_30 *ui;
};
#endif // TEST3_30_H
.cpp文件
#include "test3_30.h"
#include "ui_test3_30.h"
#include<QFile>
#include<QFileDialog>
#include<QTabWidget>
#include<QTextStream>
#include<QMessageBox>
#include<QDebug>
#include<QTableWidgetItem>
#include<QListWidgetItem>
#include <QList>
#include <QQueue>
#include <QStack>
#include <iostream>
using namespace std;
test3_30::test3_30(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::test3_30)
{
ui->setupUi(this);
QStringList header; //建立表头
header << "0" << "1" << "2" << "3"<< "4"<< "5"<< "6"<< "7"
<< "8"<< "9"<< "10"<< "11"<< "12"<< "13"<< "14"<< "15"; //命名表头
ui->tableWidget->setColumnCount(header.size()); //设置表格的列数,必须要先设置,不然表格显示不出来
ui->tableWidget->setHorizontalHeaderLabels(header);
// ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//↑↑↑↑↑↑↑设置表头(水平头)显示模式,这里设置的是拉伸模式
ui->tableWidget->setRowCount(24); //设置表格的行数
QStringList neader; //建立表头
ui->tableWidget->setHorizontalHeaderLabels(neader);
ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//↑↑↑↑↑↑↑设置表头(垂直头)显示模式,这里设置的是拉伸模式
connect(ui->pushButton,&QPushButton::clicked,[=]()
{
filepath = QFileDialog::getOpenFileName(this); //由文件对话框获取文件路径
nowframe = 0;
openfile(filepath, nowframe);
});
connect(ui->pushButton_2,&QPushButton::clicked,[=]()
{
nowframe++;
openfile(filepath, nowframe);
// qDebug() << nowframe+1;
qDebug("第%d帧",nowframe+1);
});
connect(ui->pushButton_3,&QPushButton::clicked,[=]()
{
if (nowframe>0)
nowframe--;
openfile(filepath, nowframe);
//qDebug() << nowframe+1;
qDebug("第%d帧",nowframe+1);
});
}
void test3_30::openfile(QString filepath, int frame_idx)
{
QFile f(filepath); //创建文件对象
if (!f.open(QIODevice::ReadOnly))
{
qDebug() << "打开文件失败!";
return;
}
QTextStream output(&f);
QString lineStr; //文件的每一行的字符串
QStringList lineList;
int p[24][16];
int l = 24 * frame_idx;
for (int i = 0; i <= l + 23; i++)
{
QString lineStr = output.readLine(); //读取行
if (i >= l) //从第几行开始
{
lineList = lineStr.split(",", QString::SkipEmptyParts); //根据","开分隔开每行的列
for (int j = 0; j < 16; j++)
{
// qDebug() << list.at(j + 1);
ui->tableWidget->setItem(i % 24, j, new QTableWidgetItem(lineList.at(j + 1)));
QString a=lineList.at(j + 1);
int b=a.toInt(); //qDebug()<<b;
p[i%24][j]=b; //qDebug() << b;
}
}
}
f.close();
int m,n;
int FirstPeek_x=0,FirstPeek_y=0;
int SecondPeek_x=0,SecondPeek_y=0;
ui->listWidget->clear();
ui->listWidget_2->clear();
ui->listWidget_3->clear();
for (m = 0; m < 24; m++)
{
for (n = 0; n < 16; n++)
{
int temp = p[m][n];
if(0<m && m<23 && 0<n && n<15)//分九种情况讨论——————①中间
{
if(temp > p[m+1][n] && temp > p[m-1][n] && temp > p[m][n+1] && temp > p[m][n-1]&& temp > p[m+1][n+1]
&& temp > p[m-1][n+1] && temp > p[m-1][n-1] && temp > p[m+1][n-1] && temp >30)//_-_-(这个峰值点大小可以不改)_-_-_-_-_-_-_-_-_-
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是: ";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->setWordWrap(true);
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 0 && n == 0)//分九种情况讨论——————②左上角
{
if(temp > p[m+1][n] && temp > p[m][n+1] && temp > p[m+1][n+1]&& temp >20)
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 0 && n == 15)//分九种情况讨论——————③右上角
{
if(temp > p[m+1][n] && temp > p[m][n-1]&& temp > p[m+1][n-1]&& temp >20)
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 23 && n == 0)//分九种情况讨论——————④左下角
{
if(temp > p[m-1][n] && temp > p[m][n+1] && temp > p[m-1][n+1]&& temp >20)
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 23 && n== 15)//分九种情况讨论——————⑤右下角
{
if(temp > p[m-1][n] && temp > p[m][n-1] && temp > p[m-1][n-1]&& temp >20 )
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 0 && 0 < n && n< 15)//分九种情况讨论——————⑥上边
{
if(temp > p[m+1][n] && temp > p[m][n+1] && temp > p[m][n-1]&& temp > p[m+1][n-1] && temp > p[m+1][n+1]&& temp >20)
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(0 < m && m < 23 && n == 0)//分九种情况讨论——————⑦左边
{
if(temp > p[m-1][n] && temp > p[m+1][n] && temp > p[m][n+1] && temp > p[m+1][n+1] && temp > p[m-1][n+1]&& temp >20 )
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(0 < m && m < 23 && n ==15)//分九种情况讨论——————⑧右边
{
if(temp > p[m-1][n] && temp > p[m+1][n] && temp > p[m][n-1] && temp > p[m-1][n-1] && temp > p[m+1][n-1]&& temp >20)
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
else if(m == 23 && 0 < n && n <15)//分九种情况讨论——————⑨下边
{
if(temp > p[m-1][n] && temp > p[m][n+1] && temp > p[m][n-1] && temp > p[m-1][n+1] && temp > p[m-1][n-1]&& temp >20 )
{
QString s1 = QString::number(m);
QString s2 = QString::number(n);
QString s3 = QString::number(p[m][n]);
QString s4 = "这一帧的峰值点是:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_3->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(m,n)->setBackgroundColor(Qt::red);
if(FirstPeek_x==0) FirstPeek_x=m ,FirstPeek_y=n; //在这里我们取出两个峰值点的下标
if(FirstPeek_x!=0 && FirstPeek_y!=0) SecondPeek_x=m ,SecondPeek_y=n;
}
}
} /*第三层for循环*/
} /*第二层for循环*/
int maze[24][16]={};
int book[24][16]={};
for (int i=0;i<=23;i++) {
for (int j=0;j<=15;j++) {
if(p[i][j]>=20) //_-_-_-_-_-_-_-_-_-_-_-
maze[i][j]=p[i][j];
else
maze[i][j]=0;
}
}
for (int i=0;i<=23;i++) {
for (int j=0;j<=15;j++) {
if(maze[i][j]==0)
book[i][j]=-1;
else
book[i][j]=0;
}
}
//book[FirstPeek_x][FirstPeek_y]=1;//第一个元素已经使用标记
//book[FirstPeek_x][FirstPeek_y]=-1;//小于20的元素用-1标记
int next[5][2] = //按照顺时针方向搜索
{
{ 0,1 }, //向右
{ 1,0 }, //向下
{ 0,-1}, //向左
{ -1,0}, //向上
{ -1,-1}, //向左上
};
QStack<spot> stackDFS; //定义一个栈
spot presentspot;
presentspot._x=FirstPeek_x;
presentspot._y=FirstPeek_y;
spot beforespot;
beforespot._x=FirstPeek_x;
beforespot._y=FirstPeek_y;
stackDFS.push( presentspot );
while (stackDFS.size()>0)//当栈不为空的时候,我们开始找
{
for (int l = 0; l < 5;l++)
{
presentspot._x = presentspot._x + next[l][0];
presentspot._y = presentspot._y + next[l][1];
if (presentspot._x < 0 || presentspot._x >= 24 || presentspot._y < 0 || presentspot._y >= 16 ) { continue; }
if ( maze[presentspot._x][presentspot._y]>=20 && maze[presentspot._x][presentspot._y]<maze[beforespot._x][beforespot._y]
&& book[presentspot._x][presentspot._y] != 1 )//_-_-_-_-_-_-_-_-_-_-_-
{
QString s1 = QString::number(presentspot._x);
QString s2 = QString::number(presentspot._y);
QString s3 = QString::number(maze[presentspot._x][presentspot._y]);
QString s4 = "第一个区域的点有:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(presentspot._x,presentspot._y)->setBackgroundColor(Qt::yellow);
book[presentspot._x][presentspot._y] = 1 ;
stackDFS.push( presentspot );
l=-1;
beforespot._x = presentspot._x ;
beforespot._y = presentspot._y ;
continue;
}
if( maze[presentspot._x][presentspot._y]>=maze[beforespot._x][beforespot._y]
|| book[presentspot._x][presentspot._y] == 1 || book[presentspot._x][presentspot._y] == -1 )
{
presentspot._x = stackDFS.top()._x;
presentspot._y = stackDFS.top()._y;
if(l==4)
{
if(maze[presentspot._x][presentspot._y]==maze[FirstPeek_x][FirstPeek_y])break;
stackDFS.pop();
presentspot._x = stackDFS.top()._x;
presentspot._y = stackDFS.top()._y;
beforespot._x = presentspot._x ;
beforespot._y = presentspot._y ;
l=-1;
}
continue;
}
}
qDebug("这没问题");
break;
}
QStack<spot> stackDFS_2; //定义一个栈
spot presentspot_2;
presentspot_2._x=SecondPeek_x;
presentspot_2._y=SecondPeek_y;
spot beforespot_2;
beforespot_2._x=SecondPeek_x;
beforespot_2._y=SecondPeek_y;
stackDFS_2.push( presentspot_2 ); //把第一个元素压入栈
while (stackDFS_2.size()>0)//当栈不为空的时候,我们开始找
{
for (int l = 0; l < 5;l++)
{
presentspot_2._x = presentspot_2._x + next[l][0];
presentspot_2._y = presentspot_2._y + next[l][1];
if (presentspot_2._x < 0 || presentspot_2._x >= 24 || presentspot_2._y < 0 || presentspot_2._y >= 16 ) { continue; }
if ( maze[presentspot_2._x][presentspot_2._y]>=20 && maze[presentspot_2._x][presentspot_2._y]<maze[beforespot_2._x][beforespot_2._y]
&& book[presentspot_2._x][presentspot_2._y] != 1 )//_-_-_-_-_-_-_-_-_-_-_-
{
QString s1 = QString::number(presentspot_2._x);
QString s2 = QString::number(presentspot_2._y);
QString s3 = QString::number(maze[presentspot_2._x][presentspot_2._y]);
QString s4 = "第二个区域的点有:";
s4+="["+s1+"]"+"["+s2+"]"+"="+s3;
ui->listWidget_2->addItem(new QListWidgetItem(s4));
ui->tableWidget->item(presentspot_2._x,presentspot_2._y)->setBackgroundColor(Qt::green);
book[presentspot_2._x][presentspot_2._y] = 1 ;
stackDFS_2.push( presentspot_2 );
l=-1;
beforespot_2._x = presentspot_2._x ;
beforespot_2._y = presentspot_2._y ;
continue;
}
if( maze[presentspot_2._x][presentspot_2._y]>=maze[beforespot_2._x][beforespot_2._y]
|| book[presentspot_2._x][presentspot_2._y] == 1 || book[presentspot_2._x][presentspot_2._y] == -1 )
{
presentspot_2._x = stackDFS_2.top()._x;
presentspot_2._y = stackDFS_2.top()._y;
if(l==4)
{
if(maze[presentspot_2._x][presentspot_2._y]==maze[SecondPeek_x][SecondPeek_y])break;
stackDFS_2.pop();
presentspot_2._x = stackDFS_2.top()._x;
presentspot_2._y = stackDFS_2.top()._y;
beforespot_2._x = presentspot_2._x ;
beforespot_2._y = presentspot_2._y ;
l=-1;
}
continue;
}
}
qDebug("这没问题");
break;
}
march[frame_idx][0]=FirstPeek_x;//{(x1,y1) (x2,y2)}
march[frame_idx][1]=FirstPeek_y;
march[frame_idx][2]=SecondPeek_x;
march[frame_idx][3]=SecondPeek_y;
if(frame_idx>=2) //设上一帧的两个点为(x1,y1) (x2,y2)
{ //那么这一帧的两个点为(X1,Y1) (X2,Y2)
int X_1=march[frame_idx][0]-march[frame_idx-1][0]; //X1-x1
int Y_1=march[frame_idx][1]-march[frame_idx-1][1]; //Y1-y1
int X_2=march[frame_idx][0]-march[frame_idx-1][2]; //X1-x2
int Y_2=march[frame_idx][1]-march[frame_idx-1][3]; //Y1-y2
if((X_1)*(X_1)+(Y_1)*(Y_1)<(X_2)*(X_2)+(Y_2)*(Y_2))//如果(X1-x1)²-(Y1-y1)²<(X1-x2)²-(Y1-y2)²
{ //那么点(X1,Y1)到点(x1,y1)比点(X1,Y1)到点(x2,y2)近
QString s1 = "上一帧的峰值点"; //又因为是每一帧和它的上一帧比较,所以横跨距离不会太大
QString s2 = "上一帧的峰值点"; //故取距离最近的点作为匹配的对象
QString s3 = QString::number(march[frame_idx-1][0]);
QString s4 = QString::number(march[frame_idx-1][1]);
QString s5 = QString::number(march[frame_idx][0]);
QString s6 = QString::number(march[frame_idx][1]);
QString s7 = QString::number(march[frame_idx-1][2]);
QString s8 = QString::number(march[frame_idx-1][3]);
QString s9 = QString::number(march[frame_idx][2]);
QString s10 = QString::number(march[frame_idx][3]);
s1+="["+s3+"]"+"["+s4+"]"+"和这一帧的峰值点"+"["+s5+"]"+"["+s6+"]"+"匹配";
s2+="["+s7+"]"+"["+s8+"]"+"和这一帧的峰值点"+"["+s9+"]"+"["+s10+"]"+"匹配";
ui->listWidget_3->setWordWrap(true);
ui->listWidget_3->addItem(new QListWidgetItem(s1));
ui->listWidget_3->addItem(new QListWidgetItem(s2));
}
}
}
int test3_30::nextframe( bool checked)
{
qDebug("nextframe");
nowframe++;
}
int test3_30::lastframe(bool checked)
{
qDebug("lastframe");
nowframe--;
}
test3_30::~test3_30()
{
delete ui;
}
实现的效果图如下
点击"adddate"按键后载入数据
随机选取一帧数据进行分析
当然,这些都是粗糙的处理。更细腻的就要用到很多高级的算法,而作为小白的我已经被吓得退缩了。
害,唏嘘!
我进军半导体制造业了,基本告别了五天八小时的白领生活,每天得和工厂设备打交道了,以后也只能记录一些工厂的生活了。