超像素SLIC算法源码阅读

article/2025/10/1 8:19:16

超像素SLIC算法源码阅读

  • 超像素SLIC算法源码阅读
    • SLIC简介
    • 源码阅读
    • 实验结果
    • 其他超像素算法对比

超像素SLIC算法源码阅读

SLIC简介

SLIC的全称Simple Linear Iterative Clustering,即简单线性迭代聚类,论文和代码链接如下:
论文传送门:SLIC Superpixels Comparedto State-of-the-Art Superpixel Methods
代码传送门:superpixels-revisited,这个Github项目是Superpixels: An Evaluation of the State-of-the-Art的作者的开源项目,对比了几乎所有有开源代码的超像素算法,本文的代码就是来自于此。

超像素的目的一般是为了降低后续图像处理的复杂度,SLIC定义的好的超像素算法要求是:(1)超像素的边界能够粘附图像边界;(2)计算速度应该快:(3)用于分割时应该能够提高分割质量

SLIC的算法流程如下:
(1)将图像分割成 S × S S×S S×S个格子,每个格子中心生成一个聚类中心
(2)将聚类中心移动到格子中心的八邻域像素中梯度最低的像素位置(避免将超像素定义在边缘上,减少噪声接种的机会)
(3)合并每一个像素和最近的聚类中心(这一步和kmeans不同的是,这里是遍历每一个聚类中心周围 2 S 2S 2S区域的像素点,而kmeans的方法是直接求距离某个像素最近的聚类中心,这种方法可以减少计算量同时使得算法复杂度与像素数量无关(这里我其实不太理解))。这里距离 D D D的定义是lab颜色空间和xy坐标空间五维空间的加权距离 d e = ( l j − l i ) 2 + ( a j − a i ) 2 + ( b j − b i ) 2 d_e=\sqrt{(l_j-l_i)^2+(a_j-a_i)^2+(b_j-b_i)^2} de=(ljli)2+(ajai)2+(bjbi)2 d s = ( x j − x i ) 2 + ( y j − y i ) 2 d_s=\sqrt{(x_j-x_i)^2+(y_j-y_i)^2} ds=(xjxi)2+(yjyi)2 D = d e 2 + N d s 2 D=\sqrt{d_e^2+Nd_s^2} D=de2+Nds2
(4)遍历所有聚类中心后,重新跟新每个聚类中心的位置(这里和kmeans算法一致了),然后 进行迭代
(5)迭代完成后进行连通域加强并且去除面积过小的超像素


源码阅读

函数DoSuperpixelSegmentation_ForGivenSuperpixelSize是主程序,其步骤大概就是将RGB图像转到Lab色域——计算Lab色域的梯度——初始化网格中心——将聚类中心初始化到网格中心的八邻域像素——聚类迭代——对联通域加强。

void SLIC::DoSuperpixelSegmentation_ForGivenSuperpixelSize(const unsigned int*	      ubuff,//原始图像const int	              width,//宽度const int	              height,//高度int*&	                  klabels,//输出的label,其实记录的是边界的位int&	                  numlabels,//输出的label的数量const int&	              superpixelsize,//一个label的像素大小const double&             compactness,//紧密度的参数const bool&               perturbseeds,//注意这是个bool变量const int                 iterations)//迭代次数
{//------------------------------------------------const int STEP = sqrt(double(superpixelsize))+0.5;//步长大小,其实就是画网格时,网格的间距//------------------------------------------------vector<double> kseedsl(0);vector<double> kseedsa(0);vector<double> kseedsb(0);vector<double> kseedsx(0);vector<double> kseedsy(0);//--------------------------------------------------m_width  = width;m_height = height;int sz = m_width*m_height;//整个像素大小//klabels.resize( sz, -1 );//--------------------------------------------------klabels = new int[sz];//一个数组for( int s = 0; s < sz; s++ ) klabels[s] = -1;//--------------------------------------------------if(1)//LAB, the default option{DoRGBtoLABConversion(ubuff, m_lvec, m_avec, m_bvec);//将颜色空间从RGB转到Lab}else//RGB{m_lvec = new double[sz]; m_avec = new double[sz]; m_bvec = new double[sz];for( int i = 0; i < sz; i++ ){m_lvec[i] = ubuff[i] >> 16 & 0xff;m_avec[i] = ubuff[i] >>  8 & 0xff;m_bvec[i] = ubuff[i]       & 0xff;}}//--------------------------------------------------vector<double> edgemag(0);if(perturbseeds) DetectLabEdges(m_lvec, m_avec, m_bvec, m_width, m_height, edgemag);//求颜色的边界,perturb是干扰的意思,这个是用来求八领域里面最小梯度的梯度的梯度值就是从这里来的//kseedsl这些值放进去之前都是零,运行完这个函数之后就是有值的了GetLABXYSeeds_ForGivenStepSize(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP, perturbseeds, edgemag);//这个应该是初始化的过程,建立网格,并且在网格中心的八领域里面寻找seedPerformSuperpixelSLIC(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, klabels, STEP, edgemag, compactness, iterations);//基于Kmeans算法进行迭代numlabels = kseedsl.size();int* nlabels = new int[sz];EnforceLabelConnectivity(klabels, m_width, m_height, nlabels, numlabels, double(sz)/double(STEP*STEP));{for(int i = 0; i < sz; i++ ) klabels[i] = nlabels[i];}if(nlabels) delete [] nlabels;
}

函数GetLABXYSeeds_ForGivenStepSize主要是完成了网格中心的初始化

void SLIC::GetLABXYSeeds_ForGivenStepSize(vector<double>&				kseedsl,vector<double>&				kseedsa,vector<double>&				kseedsb,vector<double>&				kseedsx,vector<double>&				kseedsy,const int&					STEP,//STEP这个值指的是网格间的间距是多少,即一步可以跨多长const bool&					perturbseeds,const vector<double>&       edgemag)
{const bool hexgrid = false;int numseeds(0);int n(0);//int xstrips = m_width/STEP;//int ystrips = m_height/STEP;int xstrips = (0.5+double(m_width)/double(STEP));//这里指的是有多少个步长,+0.5是为了进行四舍五入int ystrips = (0.5+double(m_height)/double(STEP));int xerr = m_width  - STEP*xstrips;if(xerr < 0){xstrips--;xerr = m_width - STEP*xstrips;}//划分网格的时候有可能会多一步,需要保证网格划分在图像内int yerr = m_height - STEP*ystrips;if(yerr < 0){ystrips--;yerr = m_height- STEP*ystrips;}double xerrperstrip = double(xerr)/double(xstrips);//每一步所包含的误差是多少double yerrperstrip = double(yerr)/double(ystrips);int xoff = STEP/2;//这个应是用来寻找中心点的位置int yoff = STEP/2;//-------------------------numseeds = xstrips*ystrips;//一共会有多少个种子点//-------------------------kseedsl.resize(numseeds);kseedsa.resize(numseeds);kseedsb.resize(numseeds);kseedsx.resize(numseeds);kseedsy.resize(numseeds);for( int y = 0; y < ystrips; y++ ){int ye = y*yerrperstrip;for( int x = 0; x < xstrips; x++ ){int xe = x*xerrperstrip;//到这个格子累计x的误差int seedx = (x*STEP+xoff+xe);//确定准确的每个种子点的x的位置if(hexgrid){ seedx = x*STEP+(xoff<<(y&0x1))+xe; seedx = min(m_width-1,seedx); }//for hex grid samplingint seedy = (y*STEP+yoff+ye);int i = seedy*m_width + seedx;//转化成在整个坐标中的位置kseedsl[n] = m_lvec[i];kseedsa[n] = m_avec[i];kseedsb[n] = m_bvec[i];kseedsx[n] = seedx;kseedsy[n] = seedy;n++;}}if(perturbseeds){PerturbSeeds(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, edgemag);}
}

函数PerturbSeeds是将聚类中心调整到8邻域像素中梯度最小的像素上,
void SLIC::PerturbSeeds(vector<double>&				kseedsl,vector<double>&				kseedsa,vector<double>&				kseedsb,vector<double>&				kseedsx,vector<double>&				kseedsy,const vector<double>&       edges)
{const int dx8[8] = {-1, -1,  0,  1, 1, 1, 0, -1};//像素的八领域const int dy8[8] = { 0, -1, -1, -1, 0, 1, 1,  1};int numseeds = kseedsl.size();//点的数量for( int n = 0; n < numseeds; n++ ){int ox = kseedsx[n];//original xint oy = kseedsy[n];//original yint oind = oy*m_width + ox;//转化成数组里面的下标int storeind = oind;for( int i = 0; i < 8; i++ ){int nx = ox+dx8[i];//new xint ny = oy+dy8[i];//new yif( nx >= 0 && nx < m_width && ny >= 0 && ny < m_height){int nind = ny*m_width + nx;if( edges[nind] < edges[storeind]){storeind = nind;//记录最小梯度的位置}}}if(storeind != oind){kseedsx[n] = storeind%m_width;kseedsy[n] = storeind/m_width;kseedsl[n] = m_lvec[storeind];kseedsa[n] = m_avec[storeind];kseedsb[n] = m_bvec[storeind];}}
}

函数PerformSuperpixelSLIC是完成整个迭代过程,其实就是一个kmeans算法的实现过程

void SLIC::PerformSuperpixelSLIC(vector<double>&				kseedsl,vector<double>&				kseedsa,vector<double>&				kseedsb,vector<double>&				kseedsx,vector<double>&				kseedsy,int*&					klabels,const int&				STEP,const vector<double>&       edgemag,const double&				M,const int               iterations)
{int sz = m_width*m_height;const int numk = kseedsl.size();//----------------int offset = STEP;//网络线之间的间距//if(STEP < 8) offset = STEP*1.5;//to prevent a crash due to a very small step size//----------------vector<double> clustersize(numk, 0);vector<double> inv(numk, 0);//to store 1/clustersize[k] valuesvector<double> sigmal(numk, 0);vector<double> sigmaa(numk, 0);vector<double> sigmab(numk, 0);vector<double> sigmax(numk, 0);vector<double> sigmay(numk, 0);vector<double> distvec(sz, DBL_MAX);//存储距离最近的seed的距离double invwt = 1.0/((STEP/M)*(STEP/M));//这个invwet其实是权衡颜色距离和空间距离的一个权重,因此参数M也就是一个权重int x1, y1, x2, y2;double l, a, b;double dist;double distxy;for( int itr = 0; itr < iterations; itr++ )//限制迭代次数{distvec.assign(sz, DBL_MAX);for( int n = 0; n < numk; n++ )//遍历所有的种子点{y1 = max(0.0, kseedsy[n]-offset);y2 = min((double)m_height, kseedsy[n]+offset);x1 = max(0.0, kseedsx[n]-offset);x2 = min((double)m_width, kseedsx[n]+offset);//限制邻域的范围(seedx + offset, seedy - offsetfor( int y = y1; y < y2; y++ )//在邻域内搜索{for( int x = x1; x < x2; x++ ){int i = y*m_width + x;l = m_lvec[i];a = m_avec[i];b = m_bvec[i];dist =	(l - kseedsl[n])*(l - kseedsl[n]) +(a - kseedsa[n])*(a - kseedsa[n]) +(b - kseedsb[n])*(b - kseedsb[n]);//颜色空间距离distxy =  (x - kseedsx[n])*(x - kseedsx[n]) +(y - kseedsy[n])*(y - kseedsy[n]);//xy空间距离//------------------------------------------------------------------------dist += distxy*invwt;//dist = sqrt(dist) + sqrt(distxy*invwt);//this is more exact//------------------------------------------------------------------------if( dist < distvec[i] ){distvec[i] = dist;//赋值距离klabels[i]  = n;//赋值label}}}}//-----------------------------------------------------------------// Recalculate the centroid and store in the seed values//-----------------------------------------------------------------//instead of reassigning memory on each iteration, just reset.sigmal.assign(numk, 0);sigmaa.assign(numk, 0);sigmab.assign(numk, 0);sigmax.assign(numk, 0);sigmay.assign(numk, 0);clustersize.assign(numk, 0);//------------------------------------//edgesum.assign(numk, 0);//------------------------------------{int ind(0);for( int r = 0; r < m_height; r++ ){for( int c = 0; c < m_width; c++ ){sigmal[klabels[ind]] += m_lvec[ind];//klabel[ind]是这个点属于那个seed,sigmal[klabel[ind]]是这个seed的l颜色域的累加和,m_lvec[ind]就是这个点l的颜色域的值sigmaa[klabels[ind]] += m_avec[ind];sigmab[klabels[ind]] += m_bvec[ind];sigmax[klabels[ind]] += c;sigmay[klabels[ind]] += r;//------------------------------------//edgesum[klabels[ind]] += edgemag[ind];//------------------------------------clustersize[klabels[ind]] += 1.0;//统计这个seed一共有多少个像素点ind++;}}}{for( int k = 0; k < numk; k++ ){if( clustersize[k] <= 0 ) clustersize[k] = 1;inv[k] = 1.0/clustersize[k];//computing inverse now to multiply, than divide later}}{for( int k = 0; k < numk; k++ ){kseedsl[k] = sigmal[k]*inv[k];//重新分配这个seed的颜色域,然后再循环到重新开始计算距离什么的kseedsa[k] = sigmaa[k]*inv[k];kseedsb[k] = sigmab[k]*inv[k];kseedsx[k] = sigmax[k]*inv[k];kseedsy[k] = sigmay[k]*inv[k];//------------------------------------//edgesum[k] *= inv[k];//------------------------------------}}}
}

函数EnforceLabelConnectivity实现了连通区域的重新赋值,之前所有的label值是聚类中心的值,通过这个函数将其统一超像素的编号,从0开始一直到最后一个超像素,然后会统计每个超像素所占的像素,如果太小的话会进行合并

void SLIC::EnforceLabelConnectivity(const int*					labels,//input labels that need to be corrected to remove stray labelsconst int					width,const int					height,int*&						nlabels,//new labelsint&						numlabels,//the number of labels changes in the end if segments are removedconst int&					K) //the number of superpixels desired by the user
{
//	const int dx8[8] = {-1, -1,  0,  1, 1, 1, 0, -1};
//	const int dy8[8] = { 0, -1, -1, -1, 0, 1, 1,  1};const int dx4[4] = {-1,  0,  1,  0};const int dy4[4] = { 0, -1,  0,  1};//四邻域const int sz = width*height;const int SUPSZ = sz/K;//每个小网格像素的大小//nlabels.resize(sz, -1);for( int i = 0; i < sz; i++ ) nlabels[i] = -1;//nlabels为经过这个函数处理输出的数组int label(0);int* xvec = new int[sz];int* yvec = new int[sz];//这连个数组都有整个图片那么大int oindex(0);int adjlabel(0);//adjacent labelfor( int j = 0; j < height; j++ )//遍历每一个像素{for( int k = 0; k < width; k++ ){if( 0 > nlabels[oindex] )//nlabels小于零应该就是还没有处理过的像素{nlabels[oindex] = label;//oindex为0时候,label也为0//--------------------// Start a new segment//--------------------xvec[0] = k;//这里存储的是像素的坐标yvec[0] = j;//-------------------------------------------------------// Quickly find an adjacent label for use later if needed//-------------------------------------------------------{for( int n = 0; n < 4; n++ ){int x = xvec[0] + dx4[n];int y = yvec[0] + dy4[n];if( (x >= 0 && x < width) && (y >= 0 && y < height) )//在图像范围内{int nindex = y*width + x;//这个是四邻域像素if(nlabels[nindex] >= 0) adjlabel = nlabels[nindex];//查看邻域里面是否有大于等于0的nlabels,如果有的话就是adjlabel}}}int count(1);for( int c = 0; c < count; c++ ){for( int n = 0; n < 4; n++ )//又是一个四邻域{int x = xvec[c] + dx4[n];int y = yvec[c] + dy4[n];if( (x >= 0 && x < width) && (y >= 0 && y < height) ){int nindex = y*width + x;if( 0 > nlabels[nindex] && labels[oindex] == labels[nindex] ) //这个邻域像素没有处理过 && 这个邻域像素的label和中心像素的label一致{xvec[count] = x;yvec[count] = y;//把坐标存进去,就是记录下有哪些坐标nlabels[nindex] = label;//向领域像素扩展count++;//因为这个count会一直增加,因此邻域也会一直扩展,知道周围没有邻域像素可以再扩izhan了为止}}}}//-------------------------------------------------------// If segment size is less then a limit, assign an// adjacent label found before, and decrement label count.//-------------------------------------------------------if(count <= SUPSZ >> 2)//这个区域太小{for( int c = 0; c < count; c++ ){int ind = yvec[c]*width+xvec[c];nlabels[ind] = adjlabel;}label--;}label++;}oindex++;}}numlabels = label;if(xvec) delete [] xvec;if(yvec) delete [] yvec;
}

实验结果

最后的实验结果如下:


在这里插入图片描述

如果注释掉EnforceLabelConnectivity函数里面去除小区域的代码块的结果是

在这里插入图片描述

所以还是加上比较好,SLIC只能整体效果看上去还是不错哈,单张图片耗时0.0845s,速度也比较快。

其他超像素算法对比

这里我顺便跑了下这个项目里的其他超像素算法,以好有个对比
(1) Felzenswalb & Huttenlocher (P. F. Felzenswalb, D. P. Huttenlocher. Efficient graph-based image segmentation. International Journal of Computer Vision, 59(2), 2004.)
单张图片耗时:0.0653s


在这里插入图片描述

(2) Constant Intensity Superpixels/Compact Superpixels (O. Veksler, Y. Boykov, P. Mehrani. Superpixels and supervoxels in anenergy optimization framework. European Conference on Computer Vision, pages 211–224, 2010.)
单张图片耗时:0.0468s


在这里插入图片描述

(3) Entropy Rate Superpixels (M. Y. Lui, O. Tuzel, S. Ramalingam, R. Chellappa. Entropy rate superpixel segmentation. Conference on Computer Vision and Pattern Recognition, pages 2097–2104, 2011.)
单张图片耗时:0.786s


在这里插入图片描述

(4) Pseudo Boolean Superpixels (Superpixels via pseudo-boolean optimization. Y. Zhang, R. Hartley, J. Mashford, and S. Burn. In International Conference on Computer Vision, 2011.)
单张图片耗时:0.0255s


在这里插入图片描述

(5) Contour Relaxed Superpixels ( C. Conrad, M. Mertz, R. Mester. Contour-relaxed superpixels. Energy Minimization Methods in Computer Vision and Pattern Recognition, volume 8081 of Lecture Notes in Computer Science, pages 280–293, 2013.)
单张图片耗时:0.430s


在这里插入图片描述

(6) Superpixels Extracted via Energy-Driven Sampling (M. van den Bergh, X. Boix, G. Roig, B. de Capitani, L. van Gool. SEEDS: Superpixels extracted via energy-driven sampling. European Conference on Computer Vision, pages 13–26, 2012.)
单张图片耗时:0.0819s


在这里插入图片描述

(7) VLFeat ( A. Vedaldi, B. Fulkerson. VLFeat: An Open and Portable Library of Computer Vision Algorithms.\url{http://www.vlfeat.org/, 2008.)
单张图片耗时:0.630s(这个结果应该是我参数没有设好)


在这里插入图片描述

(8) SNN
2018年好像又出了一个SNN专门用来生成超像素的深度神经网络框架,是基于SLIC的,但不管是效果还是速度都比SLIC要好。

总结
通过上面的退比可以发现同样的图片SLIC单张图片耗时0.0845ms,在所有算法中算比较快的,从结果来看,效果比较看上去是比较好的,与其有类似效果的有Contour Relaxed Superpixels算法,但是耗时高达400ms,但是超像素的结果对比不能仅仅从上看去的效果进行比较,本文开始的的简介中所提到的两篇文章都有定义超像素效果优良的衡量标准,如果需要详细对比各个算法间的好坏的话还是需要去细读论文和源码。


http://chatgpt.dhexx.cn/article/Nt7gxb1y.shtml

相关文章

python 超像素分割

SILC算法超像素分割&#xff08;源码实现&#xff09; 主体代码来自github.com/laixintao/slic-python-implementation 原代码中只有分割之后的小方块 即1.png 没有明显边界 没有继续进行图像分割 源码修改&#xff1a; 1.向Cluster类添加了label属性&#xff0c;以便于标记…

超像素分割学习笔记

学习目标 掌握超像素分割的原理、超像素分割方法的推导过程以及实现方法 1.1 超像素 超像素是指将具有相似纹理、颜色、亮度等特征的相邻像素聚合成某一个像素块&#xff0c;结合超像素的思想&#xff0c;这样可以使少量的像素块代替原本大量的像素。 目前超像素广泛应用于图…

SLIC超像素算法

原文出自&#xff1a;https://blog.csdn.net/Fighting_Dreamer/article/details/77170859 SLIC与目前最优超像素算法的比较 Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua, and Sabine Susstrunk 摘要 近年来&#xff0c;计算机视觉应用越来…

超像素池化全监督语义分割

Efficient semantic image segmentation with superpixel pooling 摘要 在这项工作中&#xff0c;我们评估了超像素池化层在深层网络结构中用于语义分割的应用。超像素池化是一种灵活有效的方法&#xff0c;可以替代其他包含空z间先验信息的池策略。我们提出了一个简单而高效…

SLIC超像素分割算法

SLIC超像素分割算法 《SLIC Superpixels》 摘要 超像素在计算机视觉应用中越来越受欢迎。然而&#xff0c;很少有算法能够输出所需数量的规则、紧凑的超级像素&#xff0c;并且计算开销低。我们介绍了一种新的算法&#xff0c;将像素聚类在组合的五维颜色和图像平面空间中&a…

matlab 超像素合并,超像素区域合并

应广大学术同行的请求,将以往研究的一些代码进行整理,特发布一个学术版本的小软件工具:SuperpixelMerge, 基本功能:实现超像素的区域合并 参数说明:共7个参数,分别为图像路径、超像素分割标记图像路径、输出结果路径、合并准则、合并后区域个数、形状参数、紧凑度参数。详…

超像素—学习笔记

文章目录 概念超像素判别条件超像素初始化的方法超像素算法SLIC算法 参考资料 概念 超像素由一系列位置相邻且颜色、亮度、纹理等特征相似的像素点组成的小区域。这些小区域大多保留了进一步进行图像分割的有效信息&#xff0c;且一般不会破坏图像中物体的边界信息。 超像素是…

超像素采样网络(英伟达)

Superpixel Sampling Networks 摘要 超像素为图像数据提供了一种高效的低/中层次的表示&#xff0c;大大减少了后续视觉任务的图像基元数量。现有的超像素算法是不可微的&#xff0c;这使得它们很难集成到其他端到端可训练的深度神经网络中。我们开发了一种新的超像素采样可微…

超像素、语义分割、实例分割、全景分割

图像分割&#xff08;Image segmentation&#xff09;就是根据某些规则把图像中的像素分成不同的部分&#xff08;打上不同的标签&#xff09;。 1. 超像素&#xff08;superpixels&#xff09; 超像素并不是在普通的像素基础上继续像微观细分&#xff0c;恰恰相反的是&#…

超像素

《超像素》   超像素是一种以聚类思想为初衷的方法&#xff0c;目的是为了对较大像素的图像进行区域划分&#xff0c;来帮助理解&#xff0c;本文介绍了一个开源项目在火灾检测场景使用超像素&#xff0c;比较巧妙&#xff0c;虽然效果不是很理想&#xff0c;但是提供了一个…

超像素学习笔记(1)——概念及判别条件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、超像素的概念二、超像素判别条件&#xff1a;一般参考三个指标1.Undersegmentation Error&#xff08;UE&#xff09;——欠分割误差2.Boundary Recall&…

超像素(superpixel)——SLIC和深度学习法

定义 可以理解成在图像上做的聚类问题。超像素的做法是将感知上相似的像素组在一起&#xff0c;称为一个超像素&#xff0c;以此来提供图像数据的紧凑表示。然后在后续的处理&#xff0c;处理单位就变成了超像素&#xff0c;而不是我们常用的像素。 一般超像素的结果可以为下…

学习笔记4:ubuntu常用命令

cd //打开路径cd.. //回到上一级目录cd &#xff5e; //回到主目录ls //列表touch demo.c //创建一个“demo.c”文件mkdir project //创建一个“project”文件夹vi . //进入当前目录删除文件 pwd //显示当前路径ifconfig //查看本机IP地址mv 文件名 /PATH //移动文件到某一目…

Ubuntu常用命令(持续更新)

Ubuntu常用命令&#xff08;持续更新&#xff09; 检查更新并升级切换至root账号修改root账号密码下载文件命令wget&#xff0c;举例&#xff1a;安装.deb文件&#xff08;在文件所在目录打开终端&#xff09;查看本机ip地址&#xff08;注意和windows系统的区别ipconfig&#…

Ubuntu常用命令 (超详细版)

1.切换到 root 用户 &#xff0c;输入 “sudo -i ”, 退出 “exit” pwd 显示当前目录&#xff0c; pwd print working directory ls 列出目录下当前文件 cp 复制文件/目录 cp (源文件或目录) (目标文件或目录) cp -r 复制文件夹 包括子目录和文件 r…

Ubuntu 常用命令大全——长期不定时更新

1. 系统相关 uname -a 显示当前系统相关信息sudo 临时获取超级用户权限su root 切换 root 用户sudo shutdown 关机sudo reboot 重启sudo nautilus 进入有 root 权限的文件管理器ps -A 查看当前有哪些进程kill 5 位进程号 结束进程 sudo fdisk -l 查看磁盘信息sudo mount /dev/…

爆料一家互联网中厂的年终奖,真香。

前不久刷到宇宙条32岁员工14万的月薪截图&#xff0c;突然想起来已经快四月底了&#xff0c;正是各大互联网公司年终奖开奖的时候&#xff0c;但相比以往&#xff0c;今年互联网圈好像安静了很多。各种“凡尔赛”的年终奖金额刷屏的情况不复存在。 各家大厂都暗戳戳地分完了奖…

OPPO K9试水“捆绑销售”,消费者“赚了”还是“亏了”?

【原创】 号称“充电5分钟&#xff0c;开黑两小时”的OPPO新品K9于5月6日正式发布&#xff0c;这句“似曾相识”的OPPO“过气”广告语&#xff0c;又重新出现在了江湖&#xff0c;说是词穷也好&#xff0c;为了突出手机卖点也罢&#xff0c;反正新品是上了。 出了新品&#x…

2021年多媒体技术圈年终事件大回顾

今年的年终总结&#xff0c;虽迟但到&#xff0c;回看往年的总结&#xff1a; 2018年多媒体技术圈年终事件大回顾 2019年多媒体技术圈年终事件大回顾 2020&#xff08;我鸽了&#xff09; 以下内容均为个人见解&#xff0c;大佬轻拍~ 一月 一月属于WebRTC&#xff0c;W3C和…

OPPO AI Lab 核心岗位开放招聘:至美之路,等你加入!

国产手机越来越受青睐&#xff0c;在中国&#xff0c;更多年轻人选择 OPPO 拍照手机。 十年来&#xff0c;OPPO 一直专注手机拍照的技术创新&#xff0c;开创了“手机自拍美颜”时代。 如今&#xff0c;全球超过 2 亿年轻人正在使用 OPPO 拍照手机。 关于OPPO 使命&#xff1a…