超声检测技术

一  超声TOFD检测技术的起源和国外发展现状

TOFD(Time Of Flight Diffraction)技术是1972年国际原子能中心的哈韦尔(英国原子能权威人士-UKKAEA)提议下发展而来。TOFD最初的发展仅仅是作为定量工具,最初的想法是:使用常规技术探测到缺陷后使用TOFD进行精确的定量和监测在线设备裂纹的扩展(例如检测压力容器)。很多年以来TOFD一直在实验室里,各国做过大量实验直到八十年代才为业界所认同;在这些实验中,用事实证明了TOFD在可靠性和精度方面都是非常好的技术。

自上世纪 9O年代起,超声TOFD检测法在国外工业无损检测领域已得到广泛应用,欧、美、日均已推出相应的应用标准。1992年英国标准BS7706问世,1996年美国ASME标准将其列入规范案例2235和第ⅴ卷《无损检测》附录,2000年欧、日分别推出专用标准。用于不同壁厚的承压设备焊接接头的制造和在用检测。

二  超声TOFD检测技术国内发展现状

3.10  平行扫查(parallel scan)

探头运动方向与声束方向平行的扫查方式。

3.11  非平行扫查(non-parallel scan)

探头运动方向与声束方向垂直的扫查方式,一般指探头对称布置于焊缝中心线两侧沿焊缝长度方向(X轴)的扫查方式。

3.12  偏置非平行扫查(offset-scan)

偏移焊缝中心线一定距离的非平行扫查。

3.13  A扫描信号(A-scan signal)

超声波信号的波形显示图,通常水平轴表示声波的传播时间,垂直轴表示波幅。

3.14  TOFD图像(TOFD image)

TOFD数据的二维显示,是将扫查过程中采集的A扫描信号连续拼接而成,一个轴代表探头移动距离,另一个轴代表深度,一般用灰度表示A扫描信号的幅度。

四  超声TOFD检测原理

4.1.1  TOFD是一种利用超声波衍射现象、非基于波幅的自动超声检测方法。通常使用纵波斜探头,采用一发一收模式。

4.1.2  在工件无缺陷部位,发射超声脉冲后,首先到达接收探头的是直通波,然后是底面反射波。有缺陷存在时,在直通波和底面反射波之间,接收探头还会接收到缺陷处产生的衍射波。除上述波外,还有缺陷部位和底面因波型转换产生的横波,一般会迟于底面反射波到达接收探头。

本文为原创文章,转载请注明出处!

MFC实现三维图像绘制

绘制物体的面时考虑两个问题:

1. 如何绘制?

2. 如何消隐不可见面?

针对这两个问题,分别采取有效边表算法和Z-Buffer缓冲器算法。

有效边表:

#include “Pi3.h”
#include “T2.h”

class CAET
{
public:
CAET();
virtual ~CAET();
public:
double x;//当前扫描线与有效边交点的x坐标
int yMax;//边的最大y值
double k;//斜率的倒数(x的增量)
CPi3 ps;//边的起点
CPi3 pe;//边的终点
CAET *pNext;
CT2 ts;//起点纹理坐标
CT2 te;//终点纹理坐标
};
桶表:

#include “AET.h”
class CBucket
{
public:
CBucket();
virtual ~CBucket();
public:
int ScanLine; //扫描线
CAET *pET; //桶上的边表指针
CBucket *pNext;
};
具体绘制实现(这里涉及到物体的光照和纹理模型):

#include “Bucket.h”
#include “Vector3.h”
#include “Lighting.h”
#include “Pi3.h”
#include “Texture.h”
#include “T2.h”

class CFill
{
public:
CFill(void);
virtual ~CFill(void);
void SetPoint(CPi3 *p, int, CT2*);//类的初始化
void SetPoint(CPi3* p, int);//类的初始化
void CreateBucket();//创建桶
void CreateEdge();//边表
void AddEt(CAET *);//合并ET表
void EtOrder();//ET表排序
void Gouraud(CDC *, int,CLighting, CMaterial*,CP3, CTexture*,BOOL);//填充多边形
void Gouraud(CDC*, int, CLighting, CMaterial*, CP3);//填充多边形
CRGB Interpolation(double, double, double, CRGB, CRGB);//颜色线性插值
double Interpolation(double, double, double, double, double);//深度线性插值
CVector3 Interpolation(double, double, double, CVector3, CVector3);//法向量线性插值
CT2 Interpolation(double m, double m0, double m1, CT2 T0, CT2 T1);//纹理地址线性插值
void ClearMemory();//清理内存
void DeleteAETChain(CAET* pAET);//删除边表
CRGB GetTextureColor(double u, double v, CTexture* pTexture);//获得纹理颜色
void InitialDepthBuffer(int nWidth, int nHeight, double zDepth);//初始化深度缓冲器
public:
int PNum;//顶点个数
CT2* T;//纹理动态数组
CPi3 *P;//顶点坐标动态数组
CAET *pHeadE, *pCurrentE, *pEdge; //有效边表结点指针
CBucket *pHeadB, *pCurrentB; //桶表结点指针
double** zBuffer;//深度缓冲器
int nWidth, nHeight;//缓冲区宽度与高度
};

#include “pch.h”
#include “Fill.h”
#include “math.h”
#define ROUND(f) int(floor(f+0.5))//四舍五入宏定义

CFill::CFill(void)
{
PNum = 0;
P = NULL;
pEdge = NULL;
pHeadB = NULL;
pHeadE = NULL;
}

CFill::~CFill(void)
{
if (P != NULL)
{
delete[] P;
P = NULL;
}
for (int i = 0;i < nWidth;i++)
{
delete[] zBuffer[i];
zBuffer[i] = NULL;
}
if (zBuffer != NULL)
{
delete zBuffer;
zBuffer = NULL;
}
ClearMemory();
}

void CFill::SetPoint(CPi3 *p, int m, CT2* t)
{
if (P != NULL)
{
delete[] P;
P = NULL;
}
P = new CPi3[m];//创建一维动态数组
T = new CT2[m];
for (int i = 0; i < m; i++)
{
P[i] = p[i];
P[i].y = ROUND(P[i].y);
T[i] = t[i];
}
PNum = m;
}

void CFill::SetPoint(CPi3* p, int m)
{
if (P != NULL)
{
delete[] P;
P = NULL;
}
P = new CPi3[m];//创建一维动态数组
for (int i = 0; i < m; i++)
{
P[i] = p[i];
P[i].y = ROUND(P[i].y);
}
PNum = m;
}

void CFill::CreateBucket()//创建桶表
{
int yMin, yMax;
yMin = yMax = P[0].y;
for (int i = 0; i < PNum; i++)//查找多边形所覆盖的最小和最大扫描线
{
if (P[i].y < yMin)
{
yMin = P[i].y;//扫描线的最小值
}
if (P[i].y > yMax)
{
yMax = P[i].y;//扫描线的最大值
}
}
for (int y = yMin; y <= yMax; y++)
{
if (yMin == y)//如果是扫描线的最小值
{
pHeadB = new CBucket;//建立桶的头结点
pCurrentB = pHeadB;//pCurrentB为CBucket当前结点指针
pCurrentB->ScanLine = yMin;
pCurrentB->pET = NULL;//没有链接边表
pCurrentB->pNext = NULL;
}
else//其他扫描线
{
pCurrentB->pNext = new CBucket;//建立桶的其他结点
pCurrentB = pCurrentB->pNext;
pCurrentB->ScanLine = y;
pCurrentB->pET = NULL;
pCurrentB->pNext = NULL;
}
}
}

void CFill::CreateEdge()//创建边表
{
for (int i = 0; i < PNum; i++)
{
pCurrentB = pHeadB;
int j = (i + 1) % PNum;//边的第2个顶点,P[i]和P[j]点对构成边
if (P[i].y < P[j].y)//边的终点比起点高
{
pEdge = new CAET;
pEdge->x = P[i].x;//计算ET表的值
pEdge->yMax = P[j].y;
pEdge->k = (P[j].x – P[i].x) / (P[j].y – P[i].y);//代表1/k
pEdge->ps = P[i];//绑定顶点和颜色
pEdge->pe = P[j];
pEdge->ts= T[i];//绑定纹理
pEdge->te = T[j];
pEdge->pNext = NULL;
while (pCurrentB->ScanLine != P[i].y)//在桶内寻找当前边的yMin
{
pCurrentB = pCurrentB->pNext;//移到yMin所在的桶结点
}
}
if (P[j].y < P[i].y)//边的终点比起点低
{
pEdge = new CAET;
pEdge->x = P[j].x;
pEdge->yMax = P[i].y;
pEdge->k = (P[i].x – P[j].x) / (P[i].y – P[j].y);
pEdge->ps = P[i];
pEdge->pe = P[j];
pEdge->ts = T[i];//绑定纹理
pEdge->te = T[j];
pEdge->pNext = NULL;
while (pCurrentB->ScanLine != P[j].y)
{
pCurrentB = pCurrentB->pNext;
}
}
if (P[i].y != P[j].y)
{
pCurrentE = pCurrentB->pET;
if (pCurrentE == NULL)
{
pCurrentE = pEdge;
pCurrentB->pET = pCurrentE;
}
else
{
while (pCurrentE->pNext != NULL)
{
pCurrentE = pCurrentE->pNext;
}
pCurrentE->pNext = pEdge;
}
}
}
}

void CFill::Gouraud(CDC *pDC, int light_type,CLighting light, CMaterial* material, CP3 EyePoint, CTexture* pTexture,BOOL IfBump)//填充多边形
{
CAET *pT1 = NULL, *pT2 = NULL;
pHeadE = NULL;
for (pCurrentB = pHeadB; pCurrentB != NULL; pCurrentB = pCurrentB->pNext)
{
for (pCurrentE = pCurrentB->pET; pCurrentE != NULL; pCurrentE = pCurrentE->pNext)
{
pEdge = new CAET;
pEdge->x = pCurrentE->x;
pEdge->yMax = pCurrentE->yMax;
pEdge->k = pCurrentE->k;
pEdge->ps = pCurrentE->ps;
pEdge->pe = pCurrentE->pe;
pEdge->pNext = NULL;
pEdge->ts = pCurrentE->ts;
pEdge->te = pCurrentE->te;
pEdge->pNext = NULL;
AddEt(pEdge);
}
EtOrder();
pT1 = pHeadE;
if (pT1 == NULL)
{
return;
}
while (pCurrentB->ScanLine >= pT1->yMax)//下闭上开
{
CAET * pAETTEmp = pT1;
pT1 = pT1->pNext;
delete pAETTEmp;
pHeadE = pT1;
if (pHeadE == NULL)
return;
}
if (pT1->pNext != NULL)
{
pT2 = pT1;
pT1 = pT2->pNext;
}
while (pT1 != NULL)
{
if (pCurrentB->ScanLine >= pT1->yMax)//下闭上开
{
CAET* pAETTemp = pT1;
pT2->pNext = pT1->pNext;
pT1 = pT2->pNext;
delete pAETTemp;
}
else
{
pT2 = pT1;
pT1 = pT2->pNext;
}
}
CRGB Ca, Cb, Cf;//Ca、Cb代表边上任意点的颜色,Cf代表面上任意点的颜色
double za, zb, zf;
CVector3 va, vb, vf;
CT2 ta, tb, tf;//ta和tb代表边上任意点的纹理地址,tf代表面上任意点的纹理地址
ta = Interpolation(pCurrentB->ScanLine, pHeadE->ps.y, pHeadE->pe.y, pHeadE->ts, pHeadE->te);
tb = Interpolation(pCurrentB->ScanLine, pHeadE->pNext->ps.y, pHeadE->pNext->pe.y, pHeadE->pNext->ts, pHeadE->pNext->te);
Ca = Interpolation(pCurrentB->ScanLine, pHeadE->ps.y, pHeadE->pe.y, pHeadE->ps.c, pHeadE->pe.c);
Cb = Interpolation(pCurrentB->ScanLine, pHeadE->pNext->ps.y, pHeadE->pNext->pe.y, pHeadE->pNext->ps.c, pHeadE->pNext->pe.c);
za = Interpolation(pCurrentB->ScanLine, pHeadE->ps.y, pHeadE->pe.y, pHeadE->ps.z, pHeadE->pe.z);
zb = Interpolation(pCurrentB->ScanLine, pHeadE->pNext->ps.y, pHeadE->pNext->pe.y, pHeadE->pNext->ps.z, pHeadE->pNext->pe.z);
va = Interpolation(pCurrentB->ScanLine, pHeadE->ps.y, pHeadE->pe.y, pHeadE->ps.v, pHeadE->pe.v);
vb = Interpolation(pCurrentB->ScanLine, pHeadE->pNext->ps.y, pHeadE->pNext->pe.y, pHeadE->pNext->ps.v, pHeadE->pNext->pe.v);
BOOL Flag = FALSE;
double xb, xe;//扫描线和有效边相交区间的起点和终点坐标
for (pT1 = pHeadE; pT1 != NULL; pT1 = pT1->pNext)
{
if (Flag == FALSE)
{
xb = pT1->x;
Flag = TRUE;
}
else
{
xe = pT1->x;
for (double x = xb; x < xe; x++)//左闭右开
{
if (ROUND(x) + nWidth / 2 < nWidth && ROUND(x) + nWidth / 2 > 0 && pCurrentB->ScanLine + nHeight / 2 < nHeight && pCurrentB->ScanLine + nHeight / 2 > 0) {
zf = Interpolation(x, xb, xe, za, zb);
if (zf >= zBuffer[ROUND(x) + nWidth / 2][pCurrentB->ScanLine + nHeight / 2])//如果当前采样点的深度小于帧缓冲器中原采样点的深度)
{
tf = Interpolation(x, xb, xe, ta, tb);
tf.c = GetTextureColor(ROUND(tf.u), ROUND(tf.v), pTexture);
material->SetDiffuse(tf.c);//用纹理颜色作为材质的漫反射光反射率
material->SetAmbient(tf.c);//用纹理颜色作为材质的环境光反射率
if (light_type == 1) {
Cf = Interpolation(x, xb, xe, Ca, Cb);
}
else if (light_type == 2) {
vf = Interpolation(x, xb, xe, va, vb);
// 凹凸纹理
if (IfBump) {
CRGB frontU = GetTextureColor(ROUND(tf.u – 1), ROUND(tf.v), pTexture);
CRGB backU = GetTextureColor(ROUND(tf.u + 1), ROUND(tf.v), pTexture);
double Bu = (frontU.blue – backU.blue) / 2;
CRGB frontV = GetTextureColor(ROUND(tf.u), ROUND(tf.v – 1), pTexture);
CRGB backV = GetTextureColor(ROUND(tf.u), ROUND(tf.v + 1), pTexture);
double Bv = (frontV.blue – backV.blue) / 2;
CVector3 DNormal = CVector3(Bu, Bv, 0);
double BumpScale = 100.0;
vf = vf + BumpScale * DNormal;
vf = vf.Normalize();
}
Cf = light.Illuminate(EyePoint, CP3(ROUND(x), pCurrentB->ScanLine, zf), vf, material);
}
zBuffer[ROUND(x) + nWidth / 2][pCurrentB->ScanLine + nHeight / 2] = zf;//使用当前采样点的深度更新深度缓冲器
pDC->SetPixelV(ROUND(x), pCurrentB->ScanLine, RGB(Cf.red * 255, Cf.green * 255, Cf.blue * 255));
}
}
}
Flag = FALSE;
}
}
for (pT1 = pHeadE; pT1 != NULL; pT1 = pT1->pNext)//边的连续性
{
pT1->x = pT1->x + pT1->k;
}
}
}

void CFill::AddEt(CAET *pNewEdge)//合并ET表
{
CAET *pCE = pHeadE;
if (pCE == NULL)
{
pHeadE = pNewEdge;
pCE = pHeadE;
}
else
{
while (pCE->pNext != NULL)
{
pCE = pCE->pNext;
}
pCE->pNext = pNewEdge;
}
}
void CFill::EtOrder()//边表的冒泡排序算法
{
CAET *pT1 = NULL, *pT2 = NULL;
int Count = 1;
pT1 = pHeadE;
if (NULL == pT1)
{
return;
}
if (NULL == pT1->pNext)//如果该ET表没有再连ET表
{
return;//桶结点只有一条边,不需要排序
}
while (NULL != pT1->pNext)//统计结点的个数
{
Count++;
pT1 = pT1->pNext;
}
for (int i = 1; i < Count; i++)//冒泡排序
{
pT1 = pHeadE;
if (pT1->x > pT1->pNext->x)//按x由小到大排序
{
pT2 = pT1->pNext;
pT1->pNext = pT1->pNext->pNext;
pT2->pNext = pT1;
pHeadE = pT2;
}
else
{
if (pT1->x == pT1->pNext->x)
{
if (pT1->k > pT1->pNext->k)//按斜率由小到大排序
{
pT2 = pT1->pNext;
pT1->pNext = pT1->pNext->pNext;
pT2->pNext = pT1;
pHeadE = pT2;
}
}
}
pT1 = pHeadE;
while (pT1->pNext->pNext != NULL)
{
pT2 = pT1;
pT1 = pT1->pNext;
if (pT1->x > pT1->pNext->x)//按x由小到大排序
{
pT2->pNext = pT1->pNext;
pT1->pNext = pT1->pNext->pNext;
pT2->pNext->pNext = pT1;
pT1 = pT2->pNext;
}
else
{
if (pT1->x == pT1->pNext->x)
{
if (pT1->k > pT1->pNext->k)//按斜率由小到大排序
{
pT2->pNext = pT1->pNext;
pT1->pNext = pT1->pNext->pNext;
pT2->pNext->pNext = pT1;
pT1 = pT2->pNext;
}
}
}
}
}
}

CRGB CFill::GetTextureColor(double u, double v, CTexture* pTexture)//获得纹理颜色
{
/*检测图片的边界,防止越界*/
if (u < 0) u = 0; if (v < 0) v = 0;
if (u > pTexture->bmp.bmWidth – 1) u = pTexture->bmp.bmWidth – 1;
if (v > pTexture->bmp.bmHeight – 1) v = pTexture->bmp.bmHeight – 1;
/*查找对应纹理空间的颜色值*/
v = pTexture->bmp.bmHeight – 1 – v;
int position = ROUND(v * pTexture->bmp.bmWidthBytes + 4 * u);//颜色分量位置
COLORREF color = RGB(pTexture->image[position + 2], pTexture->image[position + 1], pTexture->image[position]);//获取颜色值
return CRGB(GetRValue(color) / 255.0, GetGValue(color) / 255.0, GetBValue(color) / 255.0);
}

CRGB CFill::Interpolation(double t, double t1, double t2, CRGB c1, CRGB c2)//颜色线性插值
{
CRGB c;
c = (t – t2) / (t1 – t2)*c1 + (t – t1) / (t2 – t1)*c2;
return c;
}

double CFill::Interpolation(double t, double t1, double t2, double z1,double z2)//线性插值
{
double z;
z = (t – t2) / (t1 – t2) * z1 + (t – t1) / (t2 – t1) * z2;
return z;
}

CVector3 CFill::Interpolation(double x, double xa, double xb, CVector3 va, CVector3 vb)//法向量线性插值
{
CVector3 v;
v = (x – xb) / (xa – xb) * va + (x – xa) / (xb – xa) * vb;
return v;
}

CT2 CFill::Interpolation(double m, double m0, double m1, CT2 T0, CT2 T1)//纹理地址线性插值
{
CT2 Texture;
Texture = (m1 – m) / (m1 – m0) * T0 + (m – m0) / (m1 – m0) * T1;
return Texture;
}

void CFill::ClearMemory()//安全删除所有桶和桶上面的边
{
DeleteAETChain(pHeadE);
CBucket *pBucket = pHeadB;
while (pBucket != NULL)// 针对每一个桶
{
CBucket * pBucketTemp = pBucket->pNext;
DeleteAETChain(pBucket->pET);
delete pBucket;
pBucket = pBucketTemp;
}
pHeadB = NULL;
pHeadE = NULL;
}

void CFill::DeleteAETChain(CAET* pAET)
{
while (pAET != NULL)
{
CAET* pAETTemp = pAET->pNext;
delete pAET;
pAET = pAETTemp;
}
}

void CFill::InitialDepthBuffer(int nWidth, int nHeight, double zDepth)//初始化深度缓冲
{
this->nWidth = nWidth, this->nHeight = nHeight;
zBuffer = new double* [nWidth];
for (int i = 0;i < nWidth;i++)
zBuffer[i] = new double[nHeight];
for (int i = 0;i < nWidth;i++)//初始化深度缓冲
for (int j = 0;j < nHeight;j++)
zBuffer[i][j] = zDepth;
}

————————————————
版权声明:本文为CSDN博主「仿生葡萄」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/uchiha_rin/article/details/122132213

本文为原创文章,转载请注明出处!

小波探测算法

目前针对声波远探测测井异常数据的识别主要方法为波形幅度法,该方法采用波形幅度值和预设的临界值对各个深度点的波形进行坏道识别,认为某深度点的波形幅度值大于临界值,则确定该深度点的波形为坏道。事实上,声波远探测可以简化视为,随着时间增加,其波形幅度出现正负交替特征,叠加后的平均幅度(或者幅度绝对值的平均)变化并不能客观反映坏道特征。为此,本发明采用基于平均幅度的总体标准差方法,进行水平井声波远探测测井资料坏道信号识别,从而实现资料质量控制。

基于平均幅度的总体标准差计算公式为:

式中Xi为一个波列中某个时刻的数据,n为波列中数据个数,QC_Ave为平均幅度,QC_Std为总体标准差。

根据实际情况设置识别阈值σ,当时则视为坏道信号。

如图5在5973.5m、5979m、5994m等深度点平均幅度QC_Ave没有明显变化,依靠QC_Ave不能有效指示坏道信号;而QC_Std在上述井段出现明显的指状尖峰特征,指示存在波形异常,判断为坏道信号,根据波形和频率分析结果(图5中第三道与第四道)已证实上述深度的存在声波远探测测井数据异常。sheng

本文为原创文章,转载请注明出处!

OpendTect基础模块

为用户提供了一个开放式的平台。用户可在平台上进行二次开发,增加新的模块和应用程序。基础模块中,OpendTect提供了以下功能:

1、数据的输入与输出:OpendTect可支持SEGY、LAS、ASCII格式的地震、钻井、测井、层位等常用数据的输入与输出。

2、地震反射层位的追踪与编辑:通过基础模块,可以在OpendTect系统中开展2D、3D地震层位的对比追踪。同时可以对其它解释软件所解释的地震反射层位进行编辑。

3、常规地震属性计算:在基础模块中可以通过等时、沿层等方式对“三瞬”、均方根振幅、平均频率、平均能量等常规地震属性进行计算、分析。

4、特有地震属性计算:OpendTect针对断层、小型褶皱及烃类异常等开发了如相似性、中值曲率、吸收系数等特有的地震属性。这些特有的地震属性较之常规属性不仅更具针对性,应用效果也得到改善。

5、频谱分解:应用频谱分解针对不同频率段提取地震属性已经被广泛应用。OpendTect在基础模块中也提供了频谱分解技术。可将时深域转换为频率域,开展不同频段地震属性提取。

6、三维可视化:在OpendTect基础平台上,可对地震数据体、层位、属性计算结果等进行立体、透视、透明等三维可视化显示。

双平方根算子地震波偏移

  1. void main()
  2. {
  3.   int b1, b2, b3, nz, ny, nx, i,j,k,kk, nshot, ndim, is,order,n;
  4.   float sz, sy, sx, o1, o2, o3, dz, dy, dx, vel0, br1, br2, br3,vel1,vel2,vel3;
  5.   float *v,*inface1,*inface2;
  6.   dz=10;
  7.   dy=20;
  8.   dx=20;
  9.   nz=80;
  10.   ny=100;
  11.   nz=100;
  12.   b1=1;
  13.   b2=1;
  14.   b3=1;
  15.   order=2;
  16.   vel1=800;
  17.   vel2=2000;
  18.   vel3=4000;
  19.   vel0=1.0/vel1;
  20.   n=nx*ny*nz;
  21.   v=new float[n];
  22.   inface1=new float[nx*ny];
  23.   inface2=new float[nx*ny];
  24.   for(i=0;i<n;i++)
  25.   {
  26.   v[i]=1.0/vel1;
  27.   }
  28.   for(i=0;i<nx*ny;i++)
  29.   {
  30.           inface1[i]=20+i*nz;
  31.   }
  32.   for(j=0;j<ny;j++)
  33.   {
  34.   for(i=0;i<nx;i++)
  35.   {
  36.                   int kk=int(700-3*i/20);
  37.                   inface2[j*nx+i]=kk;
  38.   for(k=20;k<kk;k++)
  39.   {
  40.   v[(i*ny+j)*nz+k]=1.0/vel2;
  41.   }
  42.   for(k=kk;k<nz;k++)
  43.   {
  44.   v[(i*ny+j)*nz+k]=1.0/vel3;
  45.   }
  46.   }
  47.   }
  48.   ifstream vel(“D:double_v”);
  49.   for(i=0;i<n;i++)
  50.   {
  51.   vel<<v[i]<<“t”;
  52.   }
  53.   int ngx,ngy,nsx,nsy;
  54.   float dgy,dgx,dsx,dsy;

本文为原创文章,转载请注明出处!

开源ext2read代码走读之--“\\\\.\\PhysicalDrive0”意义

在ext2read中读取ext4文件系统的代码中,读取硬盘中的信息时,定义了以下的宏,那么这个宏是什么意思呢?

#define DEVICE “\\\\.\\PhysicalDrive0″是什么意思?

由于”\”是C/C+中转义符, “\\\\.\\”就相当于\\.\,那么以上的宏定义中的“\\\.\\PhysicalDrive0”就等价于“\\.\PhysicalDrive0”

在Windows中 \\.\ 前缀用于标识设备,其中的”.”表示本地计算机。
比如\\.\PhysicalDrive0表示本机的物理驱动器0(一般是主硬盘),
\\.\COM1表示本机的1号串行口。

本文为原创文章,转载请注明出处!

c 语言读取硬盘序列号

c++读取硬盘序列号:有时在将程序或者打包库提供给第三方时,为了防止传播泛滥,或者有一定的版权问题,需要绑定特定的计算机设备。此时就需要读取计算机的一些硬件资源(硬盘、cpu、bios等),来计算一个验证码,达到一机一码的目的。

软件查看硬盘序列号

借助diskgenius查看硬盘序列号,选中硬盘,即可看到在下方有序列号。不过貌似ssd和机械硬盘的序列号格式是不一样的

ssd: 12位序列号

机械硬盘: 8位序列号

c++实现读取硬盘序列号

参考资料

(https://msdn.microsoft.com/en-us/library/aa389273(v=vs.85)

代码实现

代码实现使用的是微软提供的wmi providers库, 读取不同硬件设备有不同的类,具体查看上面的msdn链接。

– 硬盘 [win32_physicalmemory class](https://msdn.microsoft.com/en-us/library/aa394346(v=vs.85)

– cpu [win32_processor class](https://msdn.microsoft.com/en-us/library/aa394373(v=vs.85)

– bios [win32_bios class](https://msdn.microsoft.com/en-us/library/aa394077(v=vs.85)

本文为原创文章,转载请注明出处!

声波反射成像

声反射成像测井是近年来发展起来的新型声波测井方法, 通
过探测从井旁裂缝或小构造反射回来的声场, 来研究井旁介质的构
造特征。 现有的处理方法大多都直接沿用地震勘探的信号处理方
法, 因此在应用于声反射信号处理时存在不少局限性。 本文主要研
究参数估计法和径向道滤波法, 通过这两种方法来增强来自井旁裂
缝的反射信号。
通过对基于声波阵列中不同振型的慢度不同而导出的参数估
计法进行研究, 发现此波场分离方法对共接收器阵列的分离结果不
是很理想。 在对反射波慢度进行分析后, 引入了发射器阵列数据,
提出了改进的波场分离方法。 对实测声波数据应用改进的参数估计
法, 成功的压制了井眼模式波。ng

本文为原创文章,转载请注明出处!

CWP/SU处理

室内数据处理上机实习使用的是美国科罗拉多矿院开发的CWP/SU软件,该软件具有非常强大的地震勘探数据处理功能,包括:制作地震合成记录,对各种噪声的处理,动、静校正功能,叠加和偏移等。本次室内数据处理上机实习的具体内容:

  1. 熟悉CWP/SU软件功能
  2. 使用CWP/SU软件进行地震勘探数据处理,具体内容包括:
    1. 构制模型(用速度参数表示的地球物理模型)
    2. 使用susynlv等命令生成地震合成记录,然后加各种噪声来模拟实际地震记录(由于条件限制,没有实际的野外地震记录,故使用含噪声的合成地震记录来代替)
    3. 附道头字,便于后续处理
    4. 选排,将炮集记录转换成CDP道集记录
    5. 使用频率滤波等方法消除各种噪声影响
    6. 速度分析,抽道集进行速度分析,为动校正提供速度参数
    7. 动校正
    8. 叠加,叠加的结果为自激自收的时间剖面
    9. 偏移,将自激自收的时间剖面转换为深度剖面,使同相轴归位,最终用于地质解释WP

本文为原创文章,转载请注明出处!

一次Bezier曲线

EI当n=1时,Bezier曲线的控制多边形有二个控制点P0和P1,Bezier曲线是一次多项式。

当n=2时,Bezier曲线的控制多边形有三个控制点P0、P1和P2,Bezier曲线是二次多项式。

当n=3时,Bezier曲线的控制多边形有四个控制点P0、P1、P2和P3,Bezier曲线是三次多项式。

在区间〔0,1〕范围内,每个基函数均不为零,说明不能使用控制多边形对曲线的形状进行局部调整,如果要改变某一控制点位置,整条曲线都将受到影响。

根据以上性质知道,Bezier曲线是拟合曲线,在控制多边形的第一个顶点和最后一个顶点处进行插值,其形状直接受其余控制点的影响。

(1)曲线过控制多边形的起始点和终止点。

(2)曲线起始点处的一阶导数是通过第一个控制点和第二个控制点之间的矢量来定义;曲线终止点处的一阶导数是通过最后一个控制点和倒数第二个控制点之间的矢量来定义。

(3)曲线在起始点的二阶导数依赖于起始的3个控制点;曲线在终止点的二阶导数依赖于最后的3个控制点。

本文为原创文章,转载请注明出处!