主要分为以下几个步骤:
(1) 读入两张图片并分别提取SIFT特征
(2) 利用k-d tree和BBF算法进行特征匹配查找
(3) 利用RANSAC算法筛选匹配点并计算变换矩阵
(3) 图像融合
SIFT算法以及RANSAC算法都是利用的RobHess的SIFT源码,前三个步骤RobHess的源码中都有自带的示例。
(1) SIFT特征提取
直接调用RobHess源码(RobHess的SIFT源码分析:综述 )中的sift_features()函数进行默认参数的SIFT特征提取,主要代码如下:
img1_Feat = cvCloneImage(img1);//复制图1,深拷贝,用来画特征点
img2_Feat = cvCloneImage(img2);//复制图2,深拷贝,用来画特征点
//默认提取的是LOWE格式的SIFT特征点
//提取并显示第1幅图片上的特征点
n1 = sift_features( img1, &feat1 );//检测图1中的SIFT特征点,n1是图1的特征点个数
export_features("feature1.txt",feat1,n1);//将特征向量数据写入到文件
draw_features( img1_Feat, feat1, n1 );//画出特征点
cvNamedWindow(IMG1_FEAT);//创建窗口
cvShowImage(IMG1_FEAT,img1_Feat);//显示
//提取并显示第2幅图片上的特征点
n2 = sift_features( img2, &feat2 );//检测图2中的SIFT特征点,n2是图2的特征点个数
export_features("feature2.txt",feat2,n2);//将特征向量数据写入到文件
draw_features( img2_Feat, feat2, n2 );//画出特征点
cvNamedWindow(IMG2_FEAT);//创建窗口
cvShowImage(IMG2_FEAT,img2_Feat);//显示
检测出的SIFT特征点如下:
(2) 利用k-d tree和BBF算法进行特征匹配查找,并根据最近邻和次近邻距离比值进行初步筛选
也是调用RobHess源码中的函数,加上之后的一些筛选处理,主要代码如下:
//根据图1的特征点集feat1建立k-d树,返回k-d树根给kd_root
kd_root = kdtree_build( feat1, n1 );
Point pt1,pt2;//连线的两个端点
double d0,d1;//feat2中每个特征点到最近邻和次近邻的距离
int matchNum = 0;//经距离比值法筛选后的匹配点对的个数
//遍历特征点集feat2,针对feat2中每个特征点feat,选取符合距离比值条件的匹配点,放到feat的fwd_match域中
for(int i = 0; i < n2; i++ )
{
feat = feat2+i;//第i个特征点的指针
//在kd_root中搜索目标点feat的2个最近邻点,存放在nbrs中,返回实际找到的近邻点个数
int k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, KDTREE_BBF_MAX_NN_CHKS );
if( k == 2 )
{
d0 = descr_dist_sq( feat, nbrs[0] );//feat与最近邻点的距离的平方
d1 = descr_dist_sq( feat, nbrs[1] );//feat与次近邻点的距离的平方
//若d0和d1的比值小于阈值NN_SQ_DIST_RATIO_THR,则接受此匹配,否则剔除
if( d0 < d1 * NN_SQ_DIST_RATIO_THR )
{ //将目标点feat和最近邻点作为匹配点对
pt2 = Point( cvRound( feat->x ), cvRound( feat->y ) );//图2中点的坐标
pt1 = Point( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );//图1中点的坐标(feat的最近邻点)
pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点
cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );//画出连线
matchNum++;//统计匹配点对的个数
feat2[i].fwd_match = nbrs[0];//使点feat的fwd_match域指向其对应的匹配点
}
}
free( nbrs );//释放近邻数组
}
//显示并保存经距离比值法筛选后的匹配图
cvNamedWindow(IMG_MATCH1);//创建窗口
cvShowImage(IMG_MATCH1,stacked);//显示
匹配结果如下:
(3) 利用RANSAC算法筛选匹配点并计算变换矩阵
此部分最主要的是RobHess源码中的ransac_xform()函数,此函数实现了用RANSAC算法筛选匹配点,返回结果是计算好的变换矩阵。
此部分中,我利用匹配点的坐标关系,对输入的两幅图像的左右关系进行了判断,并根据结果选择使用矩阵H或H的逆阵进行变换。
所以读入的两幅要拼接的图像的左右位置关系可以随意,程序中可自动调整。
主要代码如下:
//利用RANSAC算法筛选匹配点,计算变换矩阵H,
//无论img1和img2的左右顺序,计算出的H永远是将feat2中的特征点变换为其匹配点,即将img2中的点变换为img1中的对应点
H = ransac_xform(feat2,n2,FEATURE_FWD_MATCH,lsq_homog,4,0.01,homog_xfer_err,3.0,&inliers,&n_inliers);
//若能成功计算出变换矩阵,即两幅图中有共同区域
if( H )
{
qDebug()< pt1.x的匹配点对的个数,来判断img1中是否右图
//遍历经RANSAC算法筛选后的特征点集合inliers,找到每个特征点的匹配点,画出连线
for(int i=0; ix), cvRound(feat->y));//图2中点的坐标
pt1 = Point(cvRound(feat->fwd_match->x), cvRound(feat->fwd_match->y));//图1中点的坐标(feat的匹配点)
//qDebug()<<"pt2:("<pt1:("< pt1.x)
invertNum++;
pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点
cvLine(stacked_ransac,pt1,pt2,CV_RGB(255,0,255),1,8,0);//在匹配图上画出连线
}
cvNamedWindow(IMG_MATCH2);//创建窗口
cvShowImage(IMG_MATCH2,stacked_ransac);//显示经RANSAC算法筛选后的匹配图
/*程序中计算出的变换矩阵H用来将img2中的点变换为img1中的点,正常情况下img1应该是左图,img2应该是右图。
此时img2中的点pt2和img1中的对应点pt1的x坐标的关系基本都是:pt2.x < pt1.x
若用户打开的img1是右图,img2是左图,则img2中的点pt2和img1中的对应点pt1的x坐标的关系基本都是:pt2.x > pt1.x
所以通过统计对应点变换前后x坐标大小关系,可以知道img1是不是右图。
如果img1是右图,将img1中的匹配点经H的逆阵H_IVT变换后可得到img2中的匹配点*/
//若pt2.x > pt1.x的点的个数大于内点个数的80%,则认定img1中是右图
if(invertNum > n_inliers * 0.8)
{
CvMat * H_IVT = cvCreateMat(3, 3, CV_64FC1);//变换矩阵的逆矩阵
//求H的逆阵H_IVT时,若成功求出,返回非零值
if( cvInvert(H,H_IVT) )
{
cvReleaseMat(&H);//释放变换矩阵H,因为用不到了
H = cvCloneMat(H_IVT);//将H的逆阵H_IVT中的数据拷贝到H中
cvReleaseMat(&H_IVT);//释放逆阵H_IVT
//将img1和img2对调
IplImage * temp = img2;
img2 = img1;
img1 = temp;
ui->mosaicButton->setEnabled(true);//激活全景拼接按钮
}
else//H不可逆时,返回0
{
cvReleaseMat(&H_IVT);//释放逆阵H_IVT
QMessageBox::warning(this,tr("警告"),tr("变换矩阵H不可逆"));
}
}
else
ui->mosaicButton->setEnabled(true);//激活全景拼接按钮
}
else //无法计算出变换矩阵,即两幅图中没有重合区域
{
QMessageBox::warning(this,tr("警告"),tr("两图中无公共区域"));
}经RANSAC筛选后的匹配结果如下图:
(3) 图像融合
这里有两种拼接方法:
① 简易拼接方法的过程是:首先将右图img2经变换矩阵H变换到一个新图像中,然后直接将左图img1加到新图像中,这样拼接出来会有明显的拼接缝,但也是一个初步的成品了。
② 另一种方法首先也是将右图img2经变换矩阵H变换到一个新图像中,然后图像的融合过程将目标图像分为三部分,最左边完全取自img1中的数据,中间的重合部分是两幅图像的加权平均,重合区域右边的部分完全取自img2经变换后的图像。加权平均的权重选择也有好多方法,比如可以使用最基本的取两张图像的平均值,但这样会有明显的拼接缝。这里首先计算出拼接区域的宽度,设d1,d2分别是重叠区域中的点到重叠区域左边界和右边界的距离,则使用如下公式计算重叠区域的像素值:
,这样就可以实现平滑过渡。
主要代码如下:
//若能成功计算出变换矩阵,即两幅图中有共同区域,才可以进行全景拼接
if(H)
{
//拼接图像,img1是左图,img2是右图
CalcFourCorner();//计算图2的四个角经变换后的坐标
//为拼接结果图xformed分配空间,高度为图1图2高度的较小者,根据图2右上角和右下角变换后的点的位置决定拼接图的宽度
xformed = cvCreateImage(cvSize(MIN(rightTop.x,rightBottom.x),MIN(img1->height,img2->height)),IPL_DEPTH_8U,3);
//用变换矩阵H对右图img2做投影变换(变换后会有坐标右移),结果放到xformed中
cvWarpPerspective(img2,xformed,H,CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS,cvScalarAll(0));
cvNamedWindow(IMG_MOSAIC_TEMP); //显示临时图,即只将图2变换后的图
cvShowImage(IMG_MOSAIC_TEMP,xformed);
//简易拼接法:直接将将左图img1叠加到xformed的左边
xformed_simple = cvCloneImage(xformed);//简易拼接图,克隆自xformed
cvSetImageROI(xformed_simple,cvRect(0,0,img1->width,img1->height));
cvAddWeighted(img1,1,xformed_simple,0,0,xformed_simple);
cvResetImageROI(xformed_simple);
cvNamedWindow(IMG_MOSAIC_SIMPLE);//创建窗口
cvShowImage(IMG_MOSAIC_SIMPLE,xformed_simple);//显示简易拼接图
//处理后的拼接图,克隆自xformed
xformed_proc = cvCloneImage(xformed);
//重叠区域左边的部分完全取自图1
cvSetImageROI(img1,cvRect(0,0,MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvSetImageROI(xformed,cvRect(0,0,MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvSetImageROI(xformed_proc,cvRect(0,0,MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvAddWeighted(img1,1,xformed,0,0,xformed_proc);
cvResetImageROI(img1);
cvResetImageROI(xformed);
cvResetImageROI(xformed_proc);
cvNamedWindow(IMG_MOSAIC_BEFORE_FUSION);
cvShowImage(IMG_MOSAIC_BEFORE_FUSION,xformed_proc);//显示融合之前的拼接图
//采用加权平均的方法融合重叠区域
int start = MIN(leftTop.x,leftBottom.x) ;//开始位置,即重叠区域的左边界
double processWidth = img1->width - start;//重叠区域的宽度
double alpha = 1;//img1中像素的权重
for(int i=0; iheight; i++)//遍历行
{
const uchar * pixel_img1 = ((uchar *)(img1->imageData + img1->widthStep * i));//img1中第i行数据的指针
const uchar * pixel_xformed = ((uchar *)(xformed->imageData + xformed->widthStep * i));//xformed中第i行数据的指针
uchar * pixel_xformed_proc = ((uchar *)(xformed_proc->imageData + xformed_proc->widthStep * i));//xformed_proc中第i行数据的指针
for(int j=start; jwidth; j++)//遍历重叠区域的列
{
//如果遇到图像xformed中无像素的黑点,则完全拷贝图1中的数据
if(pixel_xformed[j*3] < 50 && pixel_xformed[j*3+1] < 50 && pixel_xformed[j*3+2] < 50 )
{
alpha = 1;
}
else
{ //img1中像素的权重,与当前处理点距重叠区域左边界的距离成正比
alpha = (processWidth-(j-start)) / processWidth ;
}
pixel_xformed_proc[j*3] = pixel_img1[j*3] * alpha + pixel_xformed[j*3] * (1-alpha);//B通道
pixel_xformed_proc[j*3+1] = pixel_img1[j*3+1] * alpha + pixel_xformed[j*3+1] * (1-alpha);//G通道
pixel_xformed_proc[j*3+2] = pixel_img1[j*3+2] * alpha + pixel_xformed[j*3+2] * (1-alpha);//R通道
}
}
cvNamedWindow(IMG_MOSAIC_PROC);//创建窗口
cvShowImage(IMG_MOSAIC_PROC,xformed_proc);//显示处理后的拼接图
/*重叠区域取两幅图像的平均值,效果不好
//设置ROI,是包含重叠区域的矩形
cvSetImageROI(xformed_proc,cvRect(MIN(leftTop.x,leftBottom.x),0,img1->width-MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvSetImageROI(img1,cvRect(MIN(leftTop.x,leftBottom.x),0,img1->width-MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvSetImageROI(xformed,cvRect(MIN(leftTop.x,leftBottom.x),0,img1->width-MIN(leftTop.x,leftBottom.x),xformed_proc->height));
cvAddWeighted(img1,0.5,xformed,0.5,0,xformed_proc);
cvResetImageROI(xformed_proc);
cvResetImageROI(img1);
cvResetImageROI(xformed); //*/
/*对拼接缝周围区域进行滤波来消除拼接缝,效果不好
//在处理前后的图上分别设置横跨拼接缝的矩形ROI
cvSetImageROI(xformed_proc,cvRect(img1->width-10,0,img1->width+10,xformed->height));
cvSetImageROI(xformed,cvRect(img1->width-10,0,img1->width+10,xformed->height));
cvSmooth(xformed,xformed_proc,CV_MEDIAN,5);//对拼接缝周围区域进行中值滤波
cvResetImageROI(xformed);
cvResetImageROI(xformed_proc);
cvShowImage(IMG_MOSAIC_PROC,xformed_proc);//显示处理后的拼接图 */
/*想通过锐化解决变换后的图像失真的问题,对于扭曲过大的图像,效果不好
double a[]={ 0, -1, 0, -1, 5, -1, 0, -1, 0 };//拉普拉斯滤波核的数据
CvMat kernel = cvMat(3,3,CV_64FC1,a);//拉普拉斯滤波核
cvFilter2D(xformed_proc,xformed_proc,&kernel);//滤波
cvShowImage(IMG_MOSAIC_PROC,xformed_proc);//显示处理后的拼接图*/
}
右图经变换后的结果如下图:
简易拼接结果如下图:
使用第二种方法时,重合区域融合之前如下图:
加权平均融合之后如下图:
用Qt做了个简单的界面,如下:
还有很多不足,经常有黑边无法去除,望大家多多指正。
实验环境:
IDE是 Qt Creator 2.4.1 ,Qt版本是4.8.4 ,OpenCV版本是2.4.4 ,SIFT源码来自RobHess给出的源码
源码下载:基于SIFT特征的全景图像拼接,Qt工程: http://download.csdn.net/detail/masikkk/5702681
参考
基于SIFT特征的全景图像拼接
你可能感兴趣的:(OpenCV,计算机视觉)
AI:180-如何利用Python进行图像处理和计算机视觉任务
一键难忘
精通AI实战千例专栏合集 python 图像处理 计算机视觉
本文收录于专栏:精通AI实战千例专栏合集https://blog.csdn.net/weixin_52908342/category_11863492.html从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。每一个案例都附带关键代码,详细讲解供大家学习,希望可以帮到大家。正在不断更新中~一.探索Python在图像处理和计算机视觉任务中的应用随着人
yolo是什么,有什么优缺点以及YOLO的应用场景?
cesske
YOLO
目录前言一、yolo是什么?二、YOLO的优点三、YOLO的缺点四、YOLO的应用场景总结前言这里我们来讲一下yolo是什么,有什么优缺点?一、yolo是什么?“YOLO”在计算机视觉和深度学习领域是一个特定的算法框架,全称是“YouOnlyLookOnce”。这个算法最初由JosephRedmon、SantoshDivvala、RossGirshick和AliFarhadi在2015年提出,旨在
人机交互:面部识别_14.面部识别在虚拟现实和增强现实中的应用
zhubeibei168
机器人及导航 人机交互 vr ar 开发语言 机器人 导航与定位
14.面部识别在虚拟现实和增强现实中的应用14.1虚拟现实中的面部识别在虚拟现实(VR)环境中,面部识别技术可以显著提升用户体验,使其更加沉浸和自然。通过识别用户的面部表情,VR系统可以实时调整虚拟角色的行为,增强用户与虚拟世界的互动。14.1.1面部表情识别面部表情识别是虚拟现实中最常见的应用之一。通过摄像头捕捉用户的面部图像,使用计算机视觉算法识别出用户的表情,如微笑、惊讶、愤怒等,虚拟角色可
深度学习的应用场景及常用技术
eso1983
深度学习
深度学习作为机器学习的一个重要分支,在众多领域都有广泛的应用,以下是一些主要的应用场景及常用技术。1.应用场景1.计算机视觉图像分类描述:对图像中的内容进行分类,识别出图像中物体所属的类别。例如,在安防领域,通过对监控摄像头拍摄的图像进行分类,判断是否有可疑人员或物品出现;在电商领域,对商品图片进行分类,方便用户搜索和筛选商品。示例:识别图片中的动物是猫还是狗,或者判断一张图片是风景照还是人物照。
python调用webrtc实现视频码率控制
音视频开发老马
python webrtc 音视频
要使用Python调用WebRTC实现视频码率控制,你需要了解以下几个步骤:安装WebRTCWebRTC是一个开源的浏览器技术,可用于实现实时通信和视频会议。你可以使用它来实现视频码率控制。要安装WebRTC,你需要从官方网站下载WebRTC代码并进行编译。这可能需要一些时间,取决于你的计算机性能。实现视频流为了使用WebRTC进行视频码率控制,你需要先实现一个视频流。你可以使用OpenCV等工具
【OpenCV-Python】——图像变换&色彩空间变换&几何变换&图像模糊(滤波)&阈值处理&形态变换
柯宝最帅
OpenCV学习 opencv 计算机视觉 图像处理
目录前言:1、色彩空间变换1.1RGB色彩空间1.2GRAY色彩空间1.3YCrCb色彩空间1.4HSV色彩空间2、几何变换3、图像模糊3.1均值滤波3.2高斯滤波3.3方框滤波3.4中值滤波4、阈值处理4.1全局阈值处理4.2自适应阈值处理5、形态变换5.1形态操作内核5.2腐蚀操作5.3膨胀操作5.4高级形态操作总结前言:图像变换是指通过技术手段将图像转换为另一幅图像,如色彩空间变换、几何变换
Python-OpenCV实现运动物体检测
HackDyno
python opencv 开发语言 Python
Python-OpenCV实现运动物体检测运动物体检测是计算机视觉领域中的一个重要任务,它可以帮助我们识别并跟踪视频中的运动物体。本文将介绍如何使用Python和OpenCV库实现基于帧差法的运动物体检测。导入库首先,我们需要导入所需的库:OpenCV和NumPy。importcv2importnumpyasnp读取视频我们将从视频文件中读取帧数据。可以使用cv2.VideoCapture函数打开
OpenCV中投影变换的代码实现
AI_dataloads
opencv 计算机视觉 人工智能
目录引言技术背景变换过程完整代码展示运行结果引言投影变换是计算机视觉和图像处理领域中常用的技术之一。它可以用于将图像从一个透视关系映射到另一个透视关系,常见的应用包括图像矫正、景深变化、以及虚拟实境的创建。本文将介绍如何使用OpenCV中的cv2.warpPerspective函数进行投影变换。技术背景投影变换的核心是使用一个3x3的变换矩阵,这个矩阵将源图像中的点映射到目标图像中的对应点。这个变
《OpenCV》——图像透视转换
Kai HVZ
opencv 人工智能 计算机视觉
图像透视转换简介在OpenCV里,图像透视转换属于重要的几何变换,也被叫做投影变换。下面从原理、实现步骤、相关函数和应用场景几个方面为你详细介绍。原理实现步骤选取对应点:要在源图像和目标图像上分别找出至少四个对应的点。这些对应点不能共线,因为它们是计算透视变换矩阵的关键依据。计算透视变换矩阵:利用OpenCV的cv2.getPerspectiveTransform函数,依据前面选取的对应点来计算透
NameError: name ‘opencv‘ is not defined
两京一十三省的希望
opencv 人工智能 pycharm yolo 深度学习
NameError:name'opencv'isnotdefined错误通常意味着你在Python代码中尝试使用opencv但该名称未定义。这种情况通常发生在你尝试调用一个库或模块的功能,但没有正确导入它。如果你想使用OpenCV进行计算机视觉任务,你需要确保正确安装和导入opencv-python库。下面是一些步骤,帮助你解决这个问题。1.安装OpenCV首先,确保你已经安装了OpenCV库。在
python图像差分法目标检测_OpenCV实现帧差法检测运动目标
weixin_39708854
python图像差分法目标检测
今天的目标是用OpenCV实现对运动目标的检测,这里选用三帧帧差法。代码如下:#include#include#include#include#includedoubleThreshold_index=0;constintCONTOUR_MAX_AERA=200;voidtrackbar(intpos){Threshold_index=(double)pos;}intmain(intargc,ch
基于深度学习的大规模模型训练
SEU-WYL
深度学习dnn 深度学习 人工智能 dnn
基于深度学习的大规模模型训练涉及训练具有数百万甚至数十亿参数的深度神经网络,以处理复杂的任务,如自然语言处理、计算机视觉和语音识别。以下是关于基于深度学习的大规模模型训练的详细介绍:1.背景和动机数据和模型规模增长:随着数据量和模型复杂度的增加,传统的单机或小规模集群训练难以满足需求。计算资源需求:大规模模型训练需要大量计算资源和存储,单一设备无法满足。任务复杂性:处理复杂任务(如GPT-3、BE
【学习心得】几种特殊但非常必要学习的pip安装小知识
小oo呆
【学习心得】 学习 pip python
在学习Python全栈的过程中要接触非常多的库,很多库都是直接pipinstall就搞定了!但有一些总是特立独行!一、安装时的名字与导包时名字不同的首先举例大名鼎鼎的OpenCV#安装OpenCVpipinstallopencv-python#导包importcv2再来一个大名鼎鼎的sklearn#安装pipinstallscikit-learn#导包举例fromsklearn.preproces
基于深度学习的行人检测与识别系统:YOLOv5、YOLOv8、YOLOv10与UI界面的实现
2025年数学建模美赛
深度学习 YOLO ui 人工智能 分类
引言行人检测与识别技术作为计算机视觉领域的一个重要应用,广泛应用于智能监控、自动驾驶、公共安全等多个领域。行人检测系统的目标是通过图像或视频中的内容,自动识别并定位行人,这项任务在复杂环境中面临着不同的挑战,如多样的行人姿态、遮挡、光照变化等。近年来,深度学习的进步,尤其是目标检测领域的快速发展,为行人检测提供了强有力的支持。YOLO(YouOnlyLookOnce)系列模型,作为目前目标检测领域
基于深度学习的行人检测识别系统:YOLOv8 + UI界面 + 数据集完整实现
2025年数学建模美赛
深度学习 YOLO ui 人工智能 分类
1.引言行人检测与识别是计算机视觉中的一个重要领域,广泛应用于安防监控、智能交通、自动驾驶等多个领域。传统的行人检测方法面临着许多挑战,如低光照、复杂背景、遮挡等问题。随着深度学习技术的迅猛发展,基于卷积神经网络(CNN)的方法,尤其是YOLO(YouOnlyLookOnce)系列算法,在行人检测中取得了显著的效果。YOLOv8作为YOLO系列的最新版本,继承了YOLO一贯的高效性和准确性,在速度
visual studio/anaconda & openCV环境配置
微凉天
C++&OpenCV
实验环境win7/win10+vs2013/vs2015+opencv345VS2015安装vs2015安装界面选择自定义安装,注意选择VisualC++语言其他部分酌情根据需要选择。openCV安装OpenCV下载地址:https://opencv.org/releases.html这里使用的是3.4.5pack下载完成后,双击打开进行安装(其实更像解压)选择安装目录,这里使用的是D:\安装完成
Python从0到100(八十六):神经网络-ShuffleNet通道混合轻量级网络的深入介绍
是Dream呀
Python python 神经网络 网络
前言:零基础学Python:Python从0到100最新最全教程。想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、计算机视觉、机器学习、神经网络以及人工智能相关知识,成为学习学习和学业的先行者!欢迎大家订阅专栏:零基础学Python:Python从0到100最新
【人工智能】基于Python的机器翻译系统,从RNN到Transformer的演进与实现
蒙娜丽宁
Python杂谈 人工智能 人工智能 python 机器翻译
《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界机器翻译(MachineTranslation,MT)作为自然语言处理领域的重要应用之一,近年来受到了广泛的关注。在本篇文章中,我们将详细探讨如何使用Python实现从传统的循环神经网络(RNN)到现代Transformer模型的机器翻译系统。文章将从机
『OpenCV-Python』Trackbar控件的用法
点赞+关注+收藏=学会了推荐关注《OpenCV-Python专栏》在OpenCV中,Trackbar控件(滑块)是一个非常常用的GUI组件,用于在图像处理和计算机视觉任务中进行交互式调整参数。比如说,加载一个图片,通过一个滑块调整图片的亮度,这样便于我们用肉眼观察图片的变化。Trackbar允许用户通过拖动滑块来调整参数的值,并且会实时更新显示结果。比如上图这个例子,创建了3个Trackbar控件
『OpenCV-Python』鼠标事件
opencv
点赞+关注+收藏=学会了在使用OpenCV进行图像处理时,有时需要与图像进行交互,例如选择感兴趣区域(ROI)、标注关键点、调整参数、获取图片指定位置的颜色值等。OpenCV提供了鼠标事件支持,可以在图像窗口中通过鼠标实现丰富的交互功能。推荐《OpenCV专栏》用到的方法是cv2.setMouseCallback(window_name,on_mouse,param=None),用这个方法监听鼠标
『OpenCV-Python』视频的读取和保存
点赞+关注+收藏=学会了推荐关注《OpenCV-Python专栏》上一讲介绍了OpenCV的读取图片的方法,这一讲简单聊聊OpenCV读取和保存视频。视频的来源主要有2种,一种是本地视频文件,另一种是实时视频流,比如手机和电脑的摄像头。要读取这两种视频的方法都是一样的,只是传的参数不同而已。读取摄像头视频读取摄像头的内容并显示出来需要几步获取摄像头内容逐帧渲染importcv2cap=cv2.Vi
探索人脸识别的奥秘:基于OpenCV和Python的开源项目推荐
杭劲钰Majestic
探索人脸识别的奥秘:基于OpenCV和Python的开源项目推荐【下载地址】毕业设计-基于OpenCV和Python的人脸识别本项目源码是针对毕业生设计的一套完整的人脸识别系统,利用先进的OpenCV库结合Python编程语言实现。该项目旨在提供一个易于理解、便于修改和移植的基础框架,非常适合计算机科学及相关专业的学生作为毕业设计或课程项目使用。系统不仅涵盖了基本的人脸检测与识别功能,其简洁的代码
YOLOv10:面向下一代目标检测模型的创新探索
AgriTube
YOLO
随着计算机视觉技术的飞速发展,目标检测模型在各类应用场景中的重要性与日俱增。从自动驾驶到智能监控,目标检测的准确性和实时性都直接影响着应用的效果和用户体验。YOLO(YouOnlyLookOnce)系列作为实时目标检测的代表性模型,自发布以来便因其速度与精度的平衡性得到了广泛关注和应用。如今,随着YOLOv10的即将推出,我们站在技术的前沿,思考如何对这一模型进行革新,使其在面对复杂多变的场景时表
『OpenCV-Python』色彩空间及色彩转换
opencv
点赞+关注+收藏=学会了在计算机图像处理中,色彩空间是理解和操作图像色彩的重要基础。每一种色彩空间都有自己的适用范围。RGB是比较常见的色彩空间,除此之外比较常见的色彩空间还有GRAY、HSV、Lab、YUV等。为什么会有这么多色彩空间呢?有兼容性的原因,也有为了方便计算的原因。比如YUV这个是电视信号系统采用的,以前的老电视是黑白电视,只需要一个颜色通道,后来出现了彩色电视,为了使视频信号能够兼
什么是数字图像?
图像识别
点赞+关注+收藏=学会了什么是数字图像?本文可在公众号「德育处主任」免费阅读弄懂数字图像的概念对学习计算机视觉很有帮助。那么,什么是数字图像?字面意思,数字图像就是有数字组成图像。通常由像素(Pixel)组成,每个像素包含颜色或亮度信息。数字图像的格式包括位图和矢量图两种主要类型:位图图像(Bitmap/RasterImage):由一个个小的像素点组成,每个像素有固定的颜色或灰度值,排列组合形成完
[特殊字符]【计算机视觉必杀技】三行代码实现文档智能校正(附完整代码)
我的青春不太冷
计算机视觉 人工智能 科技 学习 Python opencv
文章目录基于四点透视变换的文档图像校正技术1.实现效果2.技术原理2.1透视变换数学模型2.2算法流程3.核心代码解析3.1.1坐标点排序3.1.2透视变换矩阵4.实验结果分析4.1中间过程可视化4.2性能指标5.应用场景5.1纸质文档电子化5.2车牌识别预处理5.3AR场景平面检测5.4工业视觉中的平面定位6.总实现代码7.结论基于四点透视变换的文档图像校正技术在计算机视觉领域,图像几何变换是实
ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 88 from C head
Garfield2005
错误bug流水账 numpy c语言 开发语言
背景numpy是一个用户科学计算的开源python库,是一个非常基础的库,现有的python库很多都会用到numpy这个库,如果你是从事计算机视觉的,这个库完全躲不过去被很多库使用,很容易出现的问题就是兼容性,特别是numpy的接口如果发生了调整,那依赖numpy的库使用起来就很容易出问题,多数情况下调整下numpy版本即可兼容性问题中,有一个很常见的问题:File"/usr/local/lib/
python 阴暗图像 亮度增强 对比度增强 去雾
weixin_37763484
python 数据挖掘 深度学习 python opencv 计算机视觉 图像处理 目标检测
背景说明最近在处理图像,发现一些样本由于逆光原因过于阴暗,影响图像识别。解决时,可以在训练样本中加入类似的图像,或者手动把相关图像进行颜色变化。这里主要介绍手工颜色变化。原始图像如下,假设你需要判断裤子的种类(牛仔裤还或棉布裤子),类似阴暗图像很难判断:网上现有的解决方法中,主要包含直方图变化和gamma变换,例如下面几篇文章OpenCV调整图像对比度和亮度、qunshansj/opencv-py
python-OpenCV图片增强
深度学习小学生
python
importnumpyasnpimportcv2defcrop_image(img,x0,y0,w,h):"""定义裁剪函数:paramimg:要处理的图片:paramx0:左上角横坐标:paramy0:左上角纵坐标:paramw:裁剪宽度:paramh:裁剪高度:return:裁剪后的图片"""returnimg[x0:x0+w,y0:y0+h]defrandom_crop(img,area_r
python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)
墨绿色的摆渡人
python OpenCV小记 python opencv 开发语言
python|OpenCV小记(一):cv2.imread(f)读取图像操作1.为什么`[:,:,0]`提取的是第一个通道(B通道)?OpenCV的通道存储格式索引操作`[:,:,0]`的解释常见误解1.为什么[:,:,0]提取的是第一个通道(B通道)?OpenCV的通道存储格式OpenCV默认读取的图像是BGR格式,即通道顺序为Blue(蓝)、Green(绿)、Red(红)。当使用cv2.imr
数据采集高并发的架构应用
3golden
.net
问题的出发点:
最近公司为了发展需要,要扩大对用户的信息采集,每个用户的采集量估计约2W。如果用户量增加的话,将会大量照成采集量成3W倍的增长,但是又要满足日常业务需要,特别是指令要及时得到响应的频率次数远大于预期。
&n
不停止 MySQL 服务增加从库的两种方式
brotherlamp
linux linux视频 linux资料 linux教程 linux自学
现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库。前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作。
一般在线增加从库有两种方式,一种是通过mysqldump备份主库,恢复到从库,mysqldump是逻辑备份,数据量大时,备份速度会很慢,锁表的时间也会很长。另一种是通过xtrabacku
Quartz——SimpleTrigger触发器
eksliang
SimpleTrigger TriggerUtils quartz
转载请出自出处:http://eksliang.iteye.com/blog/2208166 一.概述
SimpleTrigger触发器,当且仅需触发一次或者以固定时间间隔周期触发执行;
二.SimpleTrigger的构造函数
SimpleTrigger(String name, String group):通过该构造函数指定Trigger所属组和名称;
Simpl
Informatica应用(1)
18289753290
sql workflow lookup 组件 Informatica
1.如果要在workflow中调用shell脚本有一个command组件,在里面设置shell的路径;调度wf可以右键出现schedule,现在用的是HP的tidal调度wf的执行。
2.designer里面的router类似于SSIS中的broadcast(多播组件);Reset_Workflow_Var:参数重置 (比如说我这个参数初始是1在workflow跑得过程中变成了3我要在结束时还要
python 获取图片验证码中文字
酷的飞上天空
python
根据现成的开源项目 http://code.google.com/p/pytesser/改写
在window上用easy_install安装不上 看了下源码发现代码很少 于是就想自己改写一下
添加支持网络图片的直接解析
#coding:utf-8
#import sys
#reload(sys)
#sys.s
AJAX
永夜-极光
Ajax
1.AJAX功能:动态更新页面,减少流量消耗,减轻服务器负担
2.代码结构:
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
.... AJAX script goes here ...
创业OR读研
随便小屋
创业
现在研一,有种想创业的想法,不知道该不该去实施。因为对于的我情况这两者是矛盾的,可能就是鱼与熊掌不能兼得。
研一的生活刚刚过去两个月,我们学校主要的是
需求做得好与坏直接关系着程序员生活质量
aijuans
IT 生活
这个故事还得从去年换工作的事情说起,由于自己不太喜欢第一家公司的环境我选择了换一份工作。去年九月份我入职现在的这家公司,专门从事金融业内软件的开发。十一月份我们整个项目组前往北京做现场开发,从此苦逼的日子开始了。
系统背景:五月份就有同事前往甲方了解需求一直到6月份,后续几个月也完
如何定义和区分高级软件开发工程师
aoyouzi
在软件开发领域,高级开发工程师通常是指那些编写代码超过 3 年的人。这些人可能会被放到领导的位置,但经常会产生非常糟糕的结果。Matt Briggs 是一名高级开发工程师兼 Scrum 管理员。他认为,单纯使用年限来划分开发人员存在问题,两个同样具有 10 年开发经验的开发人员可能大不相同。近日,他发表了一篇博文,根据开发者所能发挥的作用划分软件开发工程师的成长阶段。
初
Servlet的请求与响应
百合不是茶
servlet get提交 java处理post提交
Servlet是tomcat中的一个重要组成,也是负责客户端和服务端的中介
1,Http的请求方式(get ,post);
客户端的请求一般都会都是Servlet来接受的,在接收之前怎么来确定是那种方式提交的,以及如何反馈,Servlet中有相应的方法, http的get方式 servlet就是都doGet(
web.xml配置详解之listener
bijian1013
java web.xml listener
一.定义
<listener>
<listen-class>com.myapp.MyListener</listen-class>
</listener>
二.作用 该元素用来注册一个监听器类。可以收到事件什么时候发生以及用什么作为响
Web页面性能优化(yahoo技术)
Bill_chen
JavaScript Ajax Web css Yahoo
1.尽可能的减少HTTP请求数 content
2.使用CDN server
3.添加Expires头(或者 Cache-control) server
4.Gzip 组件 server
5.把CSS样式放在页面的上方。 css
6.将脚本放在底部(包括内联的) javascript
7.避免在CSS中使用Expressions css
8.将javascript和css独立成外部文
【MongoDB学习笔记八】MongoDB游标、分页查询、查询结果排序
bit1129
mongodb
游标
游标,简单的说就是一个查询结果的指针。游标作为数据库的一个对象,使用它是包括
声明
打开
循环抓去一定数目的文档直到结果集中的所有文档已经抓取完
关闭游标
游标的基本用法,类似于JDBC的ResultSet(hasNext判断是否抓去完,next移动游标到下一条文档),在获取一个文档集时,可以提供一个类似JDBC的FetchSize
ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
白糖_
ORA-12514
今天通过Oracle SQL*Plus连接远端服务器的时候提示“监听程序当前无法识别连接描述符中请求服务”,遂在网上找到了解决方案:
①打开Oracle服务器安装目录\NETWORK\ADMIN\listener.ora文件,你会看到如下信息:
# listener.ora Network Configuration File: D:\database\Oracle\net
Eclipse 问题 A resource exists with a different case
bozch
eclipse
在使用Eclipse进行开发的时候,出现了如下的问题:
Description Resource Path Location TypeThe project was not built due to "A resource exists with a different case: '/SeenTaoImp_zhV2/bin/seentao'.&
编程之美-小飞的电梯调度算法
bylijinnan
编程之美
public class AptElevator {
/**
* 编程之美 小飞 电梯调度算法
* 在繁忙的时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层。
* 所有乘客都从一楼上电梯,到达某层楼后,电梯听下来,所有乘客再从这里爬楼梯到自己的目的层。
* 在一楼时,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层。
* 问:电梯停在哪
SQL注入相关概念
chenbowen00
sql Web 安全
SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
首先让我们了解什么时候可能发生SQ
[光与电]光子信号战防御原理
comsci
原理
无论是在战场上,还是在后方,敌人都有可能用光子信号对人体进行控制和攻击,那么采取什么样的防御方法,最简单,最有效呢?
我们这里有几个山寨的办法,可能有些作用,大家如果有兴趣可以去实验一下
根据光
oracle 11g新特性:Pending Statistics
daizj
oracle dbms_stats
oracle 11g新特性:Pending Statistics 转
从11g开始,表与索引的统计信息收集完毕后,可以选择收集的统信息立即发布,也可以选择使新收集的统计信息处于pending状态,待确定处于pending状态的统计信息是安全的,再使处于pending状态的统计信息发布,这样就会避免一些因为收集统计信息立即发布而导致SQL执行计划走错的灾难。
在 11g 之前的版本中,D
快速理解RequireJs
dengkane
jquery requirejs
RequireJs已经流行很久了,我们在项目中也打算使用它。它提供了以下功能:
声明不同js文件之间的依赖
可以按需、并行、延时载入js库
可以让我们的代码以模块化的方式组织
初看起来并不复杂。 在html中引入requirejs
在HTML中,添加这样的 <script> 标签:
<script src="/path/to
C语言学习四流程控制if条件选择、for循环和强制类型转换
dcj3sjt126com
c
# include <stdio.h>
int main(void)
{
int i, j;
scanf("%d %d", &i, &j);
if (i > j)
printf("i大于j\n");
else
printf("i小于j\n");
retu
dictionary的使用要注意
dcj3sjt126com
IO
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
user.user_id , @"id",
user.username , @"username",
Android 中的资源访问(Resource)
finally_m
xml android String drawable color
简单的说,Android中的资源是指非代码部分。例如,在我们的Android程序中要使用一些图片来设置界面,要使用一些音频文件来设置铃声,要使用一些动画来显示特效,要使用一些字符串来显示提示信息。那么,这些图片、音频、动画和字符串等叫做Android中的资源文件。
在Eclipse创建的工程中,我们可以看到res和assets两个文件夹,是用来保存资源文件的,在assets中保存的一般是原生
Spring使用Cache、整合Ehcache
234390216
spring cache ehcache @Cacheable
Spring使用Cache
从3.1开始,Spring引入了对Cache的支持。其使用方法和原理都类似于Spring对事务管理的支持。Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的
当druid遇上oracle blob(clob)
jackyrong
oracle
http://blog.csdn.net/renfufei/article/details/44887371
众所周知,Oracle有很多坑, 所以才有了去IOE。
在使用Druid做数据库连接池后,其实偶尔也会碰到小坑,这就是使用开源项目所必须去填平的。【如果使用不开源的产品,那就不是坑,而是陷阱了,你都不知道怎么去填坑】
用Druid连接池,通过JDBC往Oracle数据库的
easyui datagrid pagination获得分页页码、总页数等信息
ldzyz007
var grid = $('#datagrid');
var options = grid.datagrid('getPager').data("pagination").options;
var curr = options.pageNumber;
var total = options.total;
var max =
浅析awk里的数组
nigelzeng
二维数组 array 数组 awk
awk绝对是文本处理中的神器,它本身也是一门编程语言,还有许多功能本人没有使用到。这篇文章就单单针对awk里的数组来进行讨论,如何利用数组来帮助完成文本分析。
有这么一组数据:
abcd,91#31#2012-12-31 11:24:00
case_a,136#19#2012-12-31 11:24:00
case_a,136#23#2012-12-31 1
搭建 CentOS 6 服务器(6) - TigerVNC
rensanning
centos
安装GNOME桌面环境
# yum groupinstall "X Window System" "Desktop"
安装TigerVNC
# yum -y install tigervnc-server tigervnc
启动VNC服务
# /etc/init.d/vncserver restart
# vncser
Spring 数据库连接整理
tomcat_oracle
spring bean jdbc
1、数据库连接jdbc.properties配置详解 jdbc.url=jdbc:hsqldb:hsql://localhost/xdb jdbc.username=sa jdbc.password= jdbc.driver=不同的数据库厂商驱动,此处不一一列举 接下来,详细配置代码如下:
Spring连接池  
Dom4J解析使用xpath java.lang.NoClassDefFoundError: org/jaxen/JaxenException异常
xp9802
用Dom4J解析xml,以前没注意,今天使用dom4j包解析xml时在xpath使用处报错
异常栈:java.lang.NoClassDefFoundError: org/jaxen/JaxenException异常
导入包 jaxen-1.1-beta-6.jar 解决;
&nb