在这里研究了一下各种排序算法,写一篇如何由图片一键生成颜色条的方法。


1 关于大量颜色排序

假设有大量颜色怎么对其进行排序呢,首先想到的最简单方法就是将其按照RGB值的大小进行排序,为了方便展示颜色条,这里编写了一个颜色条展示函数:

function showCM(CList)
if nargin<1,CList=winter();end
fig=figure('Units','normalized','Position',[0,50/100,1,7/100]);
ax=gca(fig);hold on
ax.XLim=[0,1];
ax.YLim=[0,1];
ax.Position=[0,0,1,1];
ax.XColor='none';
ax.YColor='none';
C=[];
C(:,:,1)=repmat([CList(:,1)',nan],[2,1]);
C(:,:,2)=repmat([CList(:,2)',nan],[2,1]);
C(:,:,3)=repmat([CList(:,3)',nan],[2,1]);
[XMesh,YMesh]=meshgrid(linspace(0,1,size(CList,1)+1),[0,1]);
surface(XMesh,YMesh,XMesh.*0,'CData',C,'EdgeColor','none');
end

假设对于RGB颜色,先按照R通道数值进行排序,R相同时通过G通道进行排序,G通道相同时通过B通道进行排序,即以[R,G,B]为排序依据时:

[R,G,B]=meshgrid(0:15:255,0:15:255,0:15:255);
CList=[R(:),G(:),B(:)]./255;[~,ind]=sortrows(CList,[1,2,3]);
NCList=CList(ind,:);showCM(NCList)


展示一下其他排序依据时的排序结果:
[R,B,G]

[G,R,B]

[G,B,R]

[B,R,G]

[B,G,R]

只能说都排得一般,要么断断续续,要么一段一段的。考虑加入灰度影响:

[R,G,B]=meshgrid(0:15:255,0:15:255,0:15:255);
CList=[R(:),G(:),B(:)]./255;Gy=rgb2gray(reshape(CList,[],1,3));
[~,ind]=sortrows([CList,Gy],[4,2,3,1]);
NCList=CList(ind,:);showCM(NCList)


大局上看起来还不错不过细节上颜色变化更剧烈更不连续了。。。那考虑一下HSV空间呢?

[R,G,B]=meshgrid(0:15:255,0:15:255,0:15:255);
CList=[R(:),G(:),B(:)]./255;hsvList=rgb2hsv(CList);
[~,ind]=sortrows(hsvList,[1,2,3]);
NCList=CList(ind,:);showCM(NCList)

[H,S,V]

[H,V,S]

[S,H,V]

[S,V,H]

[V,H,S]

[V,S,H]

可以看到大部分排序都是整体还凑活但是局部非常不连续,有没有啥局部比较连续的算法呢?

我们很容易想到旅行商算法,但是旅行商算法求解困难,这里使用由Alan Zucconi提出来的近似于最小生成书生成过程的旅行商算法,就像最小生成树一样不断把最近的点加入树中,但是生成的结果没有树枝:

function NCList=NTraveler(CList)
% 想法来自: Alan Zucconi
N=size(CList,1);
NCList=zeros(N,3);
ind=find(sum(CList,2)==min(sum(CList,2)),1);
NCList(1,:)=CList(ind,:);
CList(ind,:)=[];
for i=2:NlastColor=NCList(i-1,:);normList=vecnorm((lastColor-CList)');ind=find(normList==min(normList),1);NCList(i,:)=CList(ind,:);CList(ind,:)=[];
end
end

使用该算法排序:

[R,G,B]=meshgrid(0:15:255,0:15:255,0:15:255);
CList=[R(:),G(:),B(:)]./255;NCList=NTraveler(CList);showCM(NCList)

这样整体比较乱但局部比较连续,毕竟我们造colormap的时候不可能几万个颜色甚至几十万个颜色去构造,肯定是取几个颜色进行插值。


2 颜色聚类

首先我写了个聚类结果展示函数:

function showCluster(ColorList,index,C)
colorNum=size(C,1);C=round(C);
RGBList=double(ColorList);
ax=gca;hold on;grid on;view(3)
STR{colorNum}='';
for i=1:colorNumscatter3(RGBList(index==i,1),RGBList(index==i,2),RGBList(index==i,3),...'filled','CData',C(i,:)./255);STR{i}=[num2str(C(i,1)),' ',num2str(C(i,2)),' ',num2str(C(i,3))];
end
legend(STR,'Color',[0.9412 0.9412 0.9412],'FontName','Cambria','LineWidth',0.8,'FontSize',11,'Location','best')
ax.GridLineStyle='--';
ax.LineWidth=1.2;
ax.XLabel.String='R channel';
ax.XLabel.FontSize=13;
ax.XLabel.FontName='Cambria';
ax.YLabel.String='G channel';
ax.YLabel.FontSize=13;
ax.YLabel.FontName='Cambria';
ax.ZLabel.String='B channel';
ax.ZLabel.FontSize=13;
ax.ZLabel.FontName='Cambria';
end

这里给出两种算法的对比,一种就是直接kmeans聚类,另一种是使用MATLAB自带函数rgb2ind进行聚类,其中rgb2ind函数会快得多。

oriPic=imread('gallery\1.jpg');
colorNum=9;% kmeans聚类
RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[index,C]=kmeans(RGBList,colorNum,'Distance','sqeuclidean','MaxIter',1000,'Display','iter');showCluster(RGBList,index,C)
showCM(C./255)figure()
% rgb2ind聚类
RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[index,C]=rgb2ind(oriPic,colorNum);
index=index(:)+1;C=C.*255;showCluster(RGBList,index,C)
showCM(C./255)

示例1


kmeans


rgb2ind

示例2


kmeans


rgb2ind

示例3


kmeans


rgb2ind

可以看到两种方法聚类结果相差不大,但rgb2ind方法却快非常多。


3 少量颜色排序

降维法,类似于PCA降维法,要找到数据的主方向,之后将数据映射到主方向上来排序,以下是降维法和旅行商法对比:

oriPic=imread('gallery\1.jpg');
colorNum=8;RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[~,C]=rgb2ind(oriPic,colorNum);
% 降维法
C0=C-mean(C);
covMat=cov(C0);
[V,~]=eigs(covMat,1);
[~,ind]=sort(C0*V);
C=C(ind,:);
showCM(C)% 旅行商法
C=NTraveler(C);
showCM(C)

示例1


降维法

旅行商法

示例2


降维法

旅行商法

示例3


降维法

旅行商法

示例4


降维法

旅行商法

可以看到在色调比较简单时两种方法结果类似,但在色调比较复杂时,旅行商算法效果较好。


4 色卡直接生成

写了段代码,稍微改改颜色数量,再改改图片链接就能自动生成色卡:

oriPic=imread('gallery\1.jpg');
colorNum=8;
RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[~,C]=rgb2ind(oriPic,colorNum);
C=NTraveler(C);
disp(C)[M,N,~]=size(oriPic);
if N>Mfor i=1:colorNumoriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),1)=C(i,1).*255;oriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),2)=C(i,2).*255;oriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),3)=C(i,3).*255;end
elsefor i=1:colorNumoriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),1)=C(i,1).*255;oriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),2)=C(i,2).*255;oriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),3)=C(i,3).*255;end
end
imshow(oriPic)


5 颜色插值

写了个简单函数进行插值:

function CM=interpColor(CList,n)
Ci=1:size(CList,1);
Cq=linspace(1,size(CList,1),n);
CM=[interp1(Ci,CList(:,1),Cq,'pchip')',...interp1(Ci,CList(:,2),Cq,'pchip')',...interp1(Ci,CList(:,3),Cq,'pchip')'];
end

就举个简单的例子:

oriPic=imread('gallery\1.jpg');
colorNum=8;% 获取配色
RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[~,C]=rgb2ind(oriPic,colorNum);
C=NTraveler(C);
showCM(C)
% 插值
CM=interpColor(C,256);
showCM(CM)




6 实际应用

实际从图片取色用在绘图中:

oriPic=imread('gallery\12.jpg');
colorNum=8;% 获取配色
RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));
[~,C]=rgb2ind(oriPic,colorNum);
C=NTraveler(C);
% 插值
CM=interpColor(C,256);fig=gcf;
fig.Position=[200,200,800,600];
% 原图像
ax1=axes('Parent',fig,'Position',[0,1/2,1/2,1/2]+[1/20,1/20,-1/15,-1/15]);
ax1.NextPlot='add';axis tight
ax1.FontName='Cambria';
ax1.XColor='none';
ax1.YColor='none';
[M,N,~]=size(oriPic);
if N>Mfor i=1:colorNumoriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),1)=C(i,1).*255;oriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),2)=C(i,2).*255;oriPic(M+1:M+round(M/6),1+(round((N-1)*(i-1)/colorNum):round((N-1)*i/colorNum)),3)=C(i,3).*255;end
elsefor i=1:colorNumoriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),1)=C(i,1).*255;oriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),2)=C(i,2).*255;oriPic(1+(round((M-1)*(i-1)/colorNum):round((M-1)*i/colorNum)),N+1:N+round(N/6),3)=C(i,3).*255;end
end
image(flipud(oriPic))
% 气泡图
ax2=axes('Parent',fig,'Position',[1/2,1/2,1/2,1/2]+[1/20,1/20,-1/15,-1/15]);
ax2.NextPlot='add';grid on
ax2.GridLineStyle=':';
ax2.XMinorTick='on';
ax2.YMinorTick='on';
ax2.FontName='Cambria';
ax2.LineWidth=.7;
x=1:30;
[~,ind]=sort(rand(1,30));
x=x(ind);
y=rand(1,30);
sz=sort(rand(1,30));
bubblechart(x,y,sz,'CData',1:30);
colormap(ax2,CM)
% 折线图
ax3=axes('Parent',fig,'Position',[0,0,1/2,1/2]+[1/20,1/20,-1/15,-1/15]);
ax3.NextPlot='add';
t=linspace(0,5*pi,200);
C70=interpColor(C,70);
for i=1:70plot(t,sin(t+i.^2./700)./(10+i).*20+i.*.1,'Color',C70(i,:),'LineWidth',2);
end
% 坐标区域修饰
ax3.YLim=[0,7];
ax3.XLim=[0,5*pi];
ax3.YTick=0:.5:5;
ax3.XTick=0:1:15;
ax3.YGrid='on';
ax3.GridLineStyle='-.';
ax3.LineWidth=1;
ax3.XMinorTick='on';
ax3.YMinorTick='on';
ax3.Box='on';
ax3.FontName='Cambria';
ax3.FontSize=11;
% 曲面图
ax4=axes('Parent',fig,'Position',[1/2+1/50,0,1/2,1/2]);
ax4.NextPlot='add';grid on
ax4.Projection='perspective';
ax4.LineWidth=.8;
ax4.XMinorTick='on';
ax4.YMinorTick='on';
ax4.ZMinorTick='on';
ax4.GridLineStyle=':';
ax4.ZLim=[0,90];
ax4.FontName='Cambria';
view(-37,42)
X=linspace(0,1,100)';
CL=(-cos(X*2*pi)+1).^.2;
r=(X-.5)'.^2+(X-.5).^2;
Z=abs(ifftn(exp(7i*rand(100))./r.^.9)).*(CL*CL')*30;
surf(X,X.',Z,'EdgeColor',[.9,.9,.9],'EdgeAlpha',.1)
colormap(ax4,CM);


7 算法的进一步应用

我之前用App designer 制作过一款是色卡生成器,正好今天用文章所示算法改进一下:

Load Img(导入图片) -> 选择颜色数颜色格式 -> 点击RUN运行

之后可以点击图示处存储色卡:

色卡生成效果:

该工具完整代码:

function colourAtla
% @author slandarer% 颜色数量
colorNum=2;% 初始颜色列表
colorList=[189  115  138; 237  173  158140  199  181; 120  205  20579  148  205; 205  150  205];
% 颜色格式
% [0 1]   -> 1
% [0 255] -> 2
% #hex    -> 3
% hsv     -> 4
colorType=3;
% 三维图片矩阵
oriPic=[];
% RGB数据列
RGBList=[];
% =========================================================================
% figure窗口构建
atlaFig=uifigure('units','pixels');
atlaFig.Position=[10,65,750,500];
atlaFig.NumberTitle='off';
atlaFig.MenuBar='none';
atlaFig.Name='colour atla 1.0 | by slandarer';
atlaFig.Color=[1,1,1];
atlaFig.Resize='off';
% 显示图像axes区域
imgAxes=uiaxes('Parent',atlaFig);
imgAxes.Position=[10,10,480,480];
imgAxes.XLim=[0,100];
imgAxes.YLim=[0,100];
imgAxes.XTick=[];
imgAxes.YTick=[];
imgAxes.Box='on';
imgAxes.Toolbar.Visible='off';
% 显示色卡axes区域
atlaAxes=uiaxes('Parent',atlaFig);
atlaAxes.Position=[500,90,240,400];
atlaAxes.XLim=[0,240];
atlaAxes.YLim=[0,400];
atlaAxes.XTick=[];
atlaAxes.YTick=[];
atlaAxes.Box='on';
atlaAxes.Toolbar.Visible='on';
hold(atlaAxes,'on')
% 重绘色卡函数
function freshColorAtla(~,~)hold(atlaAxes,'off')plot(atlaAxes,[-1,-1],[-1,-1]);hold(atlaAxes,'on')text(atlaAxes,10,370,'Colour Atla','FontName','Cambria','FontSize',21);for i=1:size(colorList,1)fill(atlaAxes,[10 120 120 10],[370 370 390 390]-50-28*(i-1),colorList(i,:)./255)switch colorTypecase 1 % 显示RGB [0 1]格式颜色数据tempColorR=sprintf('%.2f',colorList(i,1)./255);tempColorG=sprintf('%.2f',colorList(i,2)./255);tempColorB=sprintf('%.2f',colorList(i,3)./255);text(atlaAxes,133,330-28*(i-1),...[tempColorR,' ',tempColorG,' ',tempColorB],...'FontName','Cambria','FontSize',16);case 2 % 显示RGB[0 255]格式颜色数据text(atlaAxes,135,330-28*(i-1),...[num2str(colorList(i,1)),' ',...num2str(colorList(i,2)),' ',...num2str(colorList(i,3))],...'FontName','Cambria','FontSize',16);case 3 % 显示16进制格式颜色数据exchange_list={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};tempColor16='#';for ii=1:3temp_num=colorList(i,ii);tempColor16(1+ii*2-1)=exchange_list{(temp_num-mod(temp_num,16))/16+1};tempColor16(1+ii*2)=exchange_list{mod(temp_num,16)+1};endtext(atlaAxes,135,330-28*(i-1),tempColor16,'FontName','Cambria','FontSize',16);case 4 % 显示hsv格式颜色数据[h,s,v]=rgb2hsv(colorList(i,1),colorList(i,2),colorList(i,3));text(atlaAxes,130,330-28*(i-1),...[sprintf('%.2f',h),'  ',...sprintf('%.2f',s),'  ',...num2str(v)],...'FontName','Cambria','FontSize',16);endendoutputData()
end
freshColorAtla()
% =========================================================================
% 选择k-means k值按钮(颜色数量按钮)
uilabel('parent',atlaFig,'Text','  ColorNum','FontName','Cambria','FontWeight','bold',...'FontSize',15,'BackgroundColor',[0.31 0.58 0.80],'position',[500,50,80,25],'FontColor',[1 1 1]);
CNsetBtn=uispinner(atlaFig,'Value',2,'limit',[2 12],'FontName','Cambria','Step',1,...'ValueDisplayFormat','%.f','FontSize',14,'ValueChangedFcn',@CNset,'position',[580,50,50,25]);
function CNset(~,~)% color number set functioncolorNum=CNsetBtn.Value;
end
% 选择颜色类型按钮
uilabel('parent',atlaFig,'Text','  ColorType','FontName','Cambria','FontWeight','bold',...'FontSize',15,'BackgroundColor',[0.31 0.58 0.80],'position',[500,15,90,25],'FontColor',[1 1 1]);
TPsetBtnGp=uidropdown('parent',atlaFig);
TPsetBtnGp.Items={'  [0 1]';'[0 255]';'  #hex';'  HSV'};
TPsetBtnGp.ValueChangedFcn=@TPset;
TPsetBtnGp.Position=[580,15,70,25];
TPsetBtnGp.Value='  #hex';
function TPset(~,~)% color type set functionswitch TPsetBtnGp.Valuecase '  [0 1]',colorType=1;case '[0 255]',colorType=2;case '  #hex', colorType=3;case '  HSV',  colorType=4;endfreshColorAtla()
end% 导入图片按钮
uibutton(atlaFig,'Text','Load Img','BackgroundColor',[0.59 0.71 0.84],'FontColor',[1 1 1],...'FontWeight','bold','Position',[640,50,100,25],'FontName','Cambria','FontSize',15,'ButtonPushedFcn',@LDimg);
function LDimg(~,~)try[filename, pathname] = uigetfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...'*.*','All Files' });oriPic=imread([pathname,filename]);[imgXLim,imgYLim,~]=size(oriPic);len=max([imgXLim,imgYLim]);imgAxes.XLim=[0 len];imgAxes.YLim=[0 len];hold(imgAxes,'off')imshow(oriPic,'Parent',imgAxes)RGBList=double(reshape(oriPic,prod(size(oriPic,[1,2])),3));catchend
end
% 开始聚类按钮
uibutton(atlaFig,'Text','RUN','BackgroundColor',[0.59 0.71 0.84],'FontColor',[1 1 1],...'FontWeight','bold','Position',[660,15,80,25],'FontName','Cambria','FontSize',15,'ButtonPushedFcn',@runKmeans);
function runKmeans(~,~)[~,C]=rgb2ind(oriPic,colorNum);C=round(NTraveler(C).*255);colorList=C;freshColorAtla()
end
% 命令行输出数据函数
function outputData(~,~)disp(['output time:',datestr(now)])disp('color list:')for i=1:size(colorList,1)switch colorType % 与色卡显示类似case 1tempData(i,:)=roundn(colorList(i,:)./255,-2);case 2tempData(i,:)=colorList(i,:);case 3exchange_list={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};tempColor16='#';for ii=1:3temp_num=colorList(i,ii);tempColor16(1+ii*2-1)=exchange_list{(temp_num-mod(temp_num,16))/16+1};tempColor16(1+ii*2)=exchange_list{mod(temp_num,16)+1};endtempData(i,1)={tempColor16};case 4[h,s,v]=rgb2hsv(colorList(i,1),colorList(i,2),colorList(i,3));tempData(i,:)=[h,s,v];endenddisp(tempData);
end
function NCList=NTraveler(CList)
% 想法来自: Alan Zucconi
N=size(CList,1);
NCList=zeros(N,3);
ind=find(sum(CList,2)==min(sum(CList,2)),1);
NCList(1,:)=CList(ind,:);
CList(ind,:)=[];
for i=2:NlastColor=NCList(i-1,:);normList=vecnorm((lastColor-CList)');ind=find(normList==min(normList),1);NCList(i,:)=CList(ind,:);CList(ind,:)=[];
end
end
end

MATLAB | 如何自然好看的从图片中提取颜色并制作色卡相关推荐

  1. 利用matlab从图片中提取曲线坐标数据

    目录 0.引言 1.思路详解与分析 2.MATLAB程序 0.引言   在读文献的时,经常遇到这样的情况:文章里提出的方法好有趣啊,好想拿文中用的数据来试试看看能不能得到相近的结果,可是文中只有根据原 ...

  2. 从Matlab的Fig图片中提取数据,并保存成csv文件

    从Matlab的Fig图片中提取数据,并保存成csv文件 1.Fig图像是由单条曲线绘制 2.Fig图像是由双条曲线绘制 3.小结 本人亲自实测有效,但能力有限,目前仅用代码测试了 Figure图片单 ...

  3. Python 图像处理 - 用PIL库提取图片中的颜色并展示为色谱实例演示,RGB颜色排序方法

    提取图片中的 RGB 颜色,通过 Luminosity 算法计算灰度值,按计算好后的灰度值进行排序并展示. # -*- coding:utf-8 -*- from PIL import Image f ...

  4. opencv获取图片像素坐标_利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)(一)

    ​某城市会展中心室内地图 背景 一名室内设计师的日常工作从设计一张会展地图开始.常常有这样的场景:划分除规范的展位后,进入销售阶段,频繁的需要修改这张地图,如展示拆分.合并.换位置.标记已交易. 问题 ...

  5. matlab下对齿轮图片的参数提取

    matlab下对齿轮图片的参数提取 目标:基于matlab对下面图片的各个参数进行提取 图片预处理: 首先读入图片,二值化,用canny算子边缘提取,由于接下来要用与中心提取,细化边缘. 代码: bw ...

  6. 利用OpenCV从图片中提取矩形并标注坐标(室内平面地图)——(一)

    某城市会展中心室内地图 背景 一名室内设计师的日常工作从设计一张会展地图开始.常常有这样的场景:划分除规范的展位后,进入销售阶段,频繁的需要修改这张地图,如展示拆分.合并.换位置.标记已交易. 问题 ...

  7. 数字信号处理综合实验——Matlab实现DTMF信号的产生与提取

    数字信号处理综合实验: 一.实验内容及要求 实验内容: 综合运用课程所学相关知识,根据实际信号的频谱特性,确定数字滤波器设计技术指标,设计相应的数字滤波器,实现DTMF信号的提取. 设计要求: (1) ...

  8. 【转】使用matlab软件打开一幅图片并且分别提取其中的RGB分量并显示

    使用matlab软件打开一幅图片并且分别提取其中的RGB分量并显示 原创 2015年10月11日 18:55:56 标签: 图片 / 5928

  9. matlab中sign函数的使用(提取符号)

    仅用于记录自己学习过程中遇到的函数 matlab中sign函数的使用,提取符号 一.语法 Y = sign(x) 返回与 x 大小相同的数组 Y,其中 Y 的每个元素是: 1,前提是 x 的对应元素大 ...

最新文章

  1. c语言如何输入汉字_C语言入门的第一个小程序
  2. bzoj1096 [ZJOI2007]仓库建设
  3. graph面板x轴模式包括哪些_发那科数控车床面板讲解
  4. html-表单初级验证
  5. php什么是变量6,PHP变量是什么
  6. matlab 局部图放大或缩小
  7. 感知机算法python实现
  8. C++函数的返回值,你不懂得!陷阱无处不在!
  9. rtabmap_ros安装---43
  10. python验证软件签名
  11. 数据库系统概念(中文版)(第6版)pdf
  12. 时序数据获取 | Python实现时间序列数据集获取
  13. 消费者行为分析包含了哪些内容?
  14. 删除文件时提示:无法读源文件或磁盘之解决办法
  15. HC Bridge容器网络模式分享
  16. MSP430F149TIMER_A的连续计数模式
  17. Session/Cookie/Token还傻傻分不清?
  18. 解决Win10系统激活office2019时出现 0xc004f074 无法激活问题,亲测可用!!!
  19. 班农注定落得如此下场
  20. 向下取整数学符号_向上取整与向下取整

热门文章

  1. Matlab可视化四维数据(用颜色表示柱坐标上某点的数值大小)
  2. QQ 红包技术方案全解密 (二)
  3. windows 问题 LoadLibrary失败,GetLastError= 193
  4. 大一上学期第十六周学习生活总结
  5. 从Android源码出发理解【易观】埋点
  6. 隔壁老王都知道的用C#+SQL Server 仓库管理系统设计和实现【建议收藏,不然看着看着就不见了】
  7. python生成数独_数独生成与求解,Python实现
  8. 求出1~100中平方根是整数的数的五种方法
  9. 编译Android8.1.0. AOSP遇到的问题(Communication error with Jack server)(Out of memory error)
  10. vue使用讯飞语音webapi