骰子点数识别之图像分割
来源:互联网 发布:感触最深的一句话知乎 编辑:程序博客网 时间:2024/05/21 07:13
链接1:利用卷积神经网络识别骰子点数
链接1:利用神经网络识别骰子点数
前言
前段时间借用神经网络和卷积神经网络实现了骰子点数的识别,但是一个很严重的问题一直困扰我,那就是当两个骰子叠在一起的时候,将两个骰子分开并不是一件简单的事情。
下图是我在识别过程中产生的不能识别的,叠加在一起的图片素材。
面对这些形态各异的图片,有的时候是两个骰子一个角连在一起,有的是一条边,有的是三个骰子叠在一起。所以,很难找到一个满意的办法解决这个问题。
第一思路就是从原始的RGB图像着手,通过调整二值化阈值,希望能够将骰子对象分割开来,但是遗憾的是我试了好几种方法,都是不行的,原因在于原图像在交接的地方本来就很模糊,颜色变化很小,所以使用二值化阈值调整很难得到完美的解决方案。
期间我尝试了不同的方法
1. 分水岭
close allclc figure(1)subplot(231)RGB_img=imread('161220S010129.jpg');imgsize =size(RGB_img);RGB_img = imcrop(RGB_img,[imgsize(1,2)*0.418 imgsize(1,1)*0.655 215 134]);%大部分图像布局固定imshow(RGB_img)%%subplot(232)%imhist(A(:,:,1));bw=im2bw(rgb2gray(RGB_img));bw=medfilt2(bw);planes=bwareaopen(bw,100);imshow(planes)%%subplot(233)D=bwdist(imcomplement(planes));D=mat2gray(D);imshow(D)figuresubimage(D)hold on[C,h]=imcontour(D,0.2:0.2:0.8);set(h,'ShowText','on','TextStep',get(h,'LevelStep')*2)text_handle = clabel(C,h,'color','g');figure(1)%%subplot(234)M=imimposemin(imcomplement(D),D>.8);imshow(M);%%subplot(236)L=watershed(M);r=L & planes;imshow(r)%%%%%%%%%%%%stats=regionprops(r,'BoundingBox','Centroid');hold onc=cat(1,stats.Centroid);plot(c(:,1),c(:,2),'r*')bb={stats.BoundingBox};cellfun(@(x) rectangle('Position',x,'EdgeColor','y'),bb)%%subplot(235)L(r)=5;imshow(L,[])
2. 抽取局部再二值化寻找连通区域
close all;RGB_img=imread('161221S010029.jpg');imgsize =size(RGB_img);RGB_img = imcrop(RGB_img,[imgsize(1,2)*0.418 imgsize(1,1)*0.655 215 134]);%大部分图像布局固定GRY_img=rgb2gray(RGB_img);level = graythresh(GRY_img);BW_img=im2bw(GRY_img,0.7);BW_img =imclearborder(BW_img,8);[img1,map] = rgb2ind(RGB_img,64); %# Create your quantized imagerPlane = reshape(map(img1+1,1),size(img1)); %# Red color plane for imagegPlane = reshape(map(img1+1,2),size(img1)); %# Green color plane for imagebPlane = reshape(map(img1+1,3),size(img1)); %# Blue color plane for imagefigure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(rPlane, []); title('R');subplot(2, 2, 2); imshow(gPlane, []); title('G');subplot(2, 2, 3); imshow(bPlane, []); title('B');subplot(2, 2, 4); imshow(GRY_img, []); title('O');figure('units', 'normalized', 'position', [0 0 1 1]);I2 = bwareaopen(BW_img,100,8);%删除二值图像BW中面积小于P的对象,默认情况下使用8邻域。cc = bwconncomp(I2,8);%bwconnecomp()是找出二值图像中连通的区域, CC返回结果,比如这样一幅图(简化便于理解):n=cc.NumObjects;%有多少个对象k = regionprops(cc,'Area','Perimeter','MajorAxisLength','MinorAxisLength','Image');%用途是get the properties of region,即用来度量图像区域属性的函数。subplot(2, 2, 1); imshow(BW_img, []); title('O');subplot(2, 2, 2); imshow(I2, []); title('G');[m,n] = find(I2==1);max_x=max(m);max_y=max(n);min_x=min(m);min_y=min(n);new_img=RGB_img(min_x:max_x,min_y:max_y,:);subplot(2, 2,3); imshow(new_img, []); title('G');new_BW_img=im2bw(new_img,0.7);subplot(2, 2,4); imshow(new_BW_img, []); title('new_BW_img');%figure('units', 'normalized', 'position', [0 0 1 1]); for i=1:n % subplot(2, 2, i); imshow(k(i).Image, []); title('T'); end
3. K-means 分类
close all; clear all; clc; C_Segments=3; img_original=imread('161224S011389.jpg');imgsize =size(img_original);img_original = imcrop(img_original,[imgsize(1,2)*0.418 imgsize(1,1)*0.655 215 134]);%大部分图像布局固定 figure,imshow(img_original),title('原始图像'); %显示原图像 img_gray=rgb2gray(img_original); figure,imshow(img_gray),title('原始灰度图像'); % 获取图像的长宽 [m,n]=size(img_gray); % 灰度阈值计算 T=graythresh(img_gray); img_bw=im2bw(img_gray,T); figure,imshow(img_bw),title('原始二值图像'); % 将图像进行RGB——3通道分解 A = reshape(img_original(:, :, 1), m*n, 1); % 将RGB分量各转为kmeans使用的数据格式n行,一样一样本 B = reshape(img_original(:, :, 2), m*n, 1); C = reshape(img_original(:, :, 3), m*n, 1); dat = [A B C]; % r g b分量组成样本的特征,每个样本有三个属性值,共width*height个样本 cRGB = kmeans(double(dat), C_Segments,... 'Distance','city',... 'emptyaction','singleton',... 'start','sample'); % 使用聚类算法分为2类 rRGB = reshape(cRGB, m, n); % 反向转化为图片形式 figure, imshow(label2rgb(rRGB)),title('RGB通道分割结果'); % 显示分割结果 % 将图像进行单一通道灰度分解 GraySeg= reshape(img_gray(:, :), m*n, 1); cGray=kmeans(double(GraySeg), 2); rGray= reshape(cGray, m, n); % 反向转化为图片形式 figure, imshow(label2rgb(rGray)),title('灰度通道分割结果'); % 显示分割结果
4.sobel 算子和watershed 这个是MATLAB官方示例
clc; clear all; close all;%第一步:读入彩色图像,将其转化成灰度图像rgb = imread('abc.jpg');if ndims(rgb) == 3 I = rgb2gray(rgb);else I = rgb;endfigure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(rgb); title('原图');subplot(1, 2, 2); imshow(I); title('灰度图');%第2步:将梯度幅值作为分割函数%使用Sobel边缘算子对图像进行水平和垂直方向的滤波,然后求取模值,sobel算子滤波后的图像在边界处会显示比较大的值,在没有边界处的值会很小。hy = fspecial('sobel');%fspecial函数用于建立预定义的滤波算子hx = hy';Iy = imfilter(double(I), hy, 'replicate');%实现线性空间滤波函数。功能:对任意类型数组或多维图像进行滤波Ix = imfilter(double(I), hx, 'replicate');gradmag = sqrt(Ix.^2 + Iy.^2);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(I,[]), title('灰度图像')subplot(1, 2, 2); imshow(gradmag,[]), title('梯度幅值图像')%%第2步:标记前景对象% 有多种方法可以应用在这里来获得前景标记,这些标记必须是前景对象内部的连接斑点像素。% 这个例子中,将使用形态学技术“基于开的重建”和“基于闭的重建”来清理图像。% 这些操作将会在每个对象内部创建单位极大值,使得可以使用imregionalmax来定位。% % 开运算和闭运算:先腐蚀后膨胀称为开;先膨胀后腐蚀称为闭。开和闭这两种运算可以除去比结构元素小的特定图像细节,% 同时保证不产生全局几何失真。开运算可以把比结构元素小的突刺滤掉,切断细长搭接而起到分离作用;% 闭运算可以把比结构元素小的缺口或孔填充上,搭接短的间隔而起到连接作用。%开操作是腐蚀后膨胀,基于开的重建(基于重建的开操作)是腐蚀后进行形态学重建。下面比较这两种方式。%% 首先,用imopen做开操作。se = strel('disk', 2);%结构元素,用于膨胀腐蚀及开闭运算等操作的结构元素对象具体用法:SE=strel(shape,parameters)创建由指定形状shape对应的结构元素。Io = imopen(I, se);%开操作是一般使对象的轮廓变得光滑,断开狭窄的间断和消除细的突出物figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(I, []); title('灰度图像');subplot(1, 2, 2); imshow(Io), title('图像开操作')%% 接下来,通过腐蚀后重建来做基于开的重建计算。Ie = imerode(I, se);Iobr = imreconstruct(Ie, I);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(I, []); title('灰度图像');subplot(1, 2, 2); imshow(Iobr, []), title('基于开的重建图像')%% 开操作后,接着进行闭操作,可以移除较暗的斑点和枝干标记。对比常规的形态学闭操作和基于闭的重建操作。首先,使用imclose:Ioc = imclose(Io, se);Ic = imclose(I, se);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(I, []); title('灰度图像');subplot(2, 2, 2); imshow(Io, []); title('开操作图像');subplot(2, 2, 3); imshow(Ic, []); title('闭操作图像');subplot(2, 2, 4); imshow(Ioc, []), title('开闭操作');%现在使用imdilate,然后使用imreconstruct。注意必须对输入图像求补,对imreconstruct输出图像求补。%IM2 = imcomplement(IM)计算图像IM的补集。IM可以是二值图像,或者RGB图像。IM2与IM有着相同的数据类型和大小。Iobrd = imdilate(Iobr, se);%利用结构元素se膨胀Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));Iobrcbr = imcomplement(Iobrcbr);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(I, []); title('灰度图像');subplot(2, 2, 2); imshow(Ioc, []); title('开闭操作');subplot(2, 2, 3); imshow(Iobr, []); title('基于开的重建图像');subplot(2, 2, 4); imshow(Iobrcbr, []), title('基于闭的重建图像');%通过比较Iobrcbr和loc可以看到,在移除小污点同时不影响对象全局形状的应用下,基于重建的开闭操作要比标准的开闭重建更加有效。%计算Iobrcbr的局部极大来得到更好的前景标记。fgm = imregionalmax(Iobrcbr);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 3, 1); imshow(I, []); title('灰度图像');subplot(1, 3, 2); imshow(Iobrcbr, []); title('基于重建的开闭操作');subplot(1, 3, 3); imshow(fgm, []); title('局部极大图像');%为了帮助理解这个结果,叠加前景标记到原图上。It1 = rgb(:, :, 1);It2 = rgb(:, :, 2);It3 = rgb(:, :, 3);It1(fgm) = 255; It2(fgm) = 0; It3(fgm) = 0;I2 = cat(3, It1, It2, It3);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(rgb, []); title('原图像');subplot(2, 2, 2); imshow(Iobrcbr, []); title('基于重建的开闭操作');subplot(2, 2, 3); imshow(fgm, []); title('局部极大图像');subplot(2, 2, 4); imshow(I2); title('局部极大叠加到原图像');%% 注意到大多闭塞处和阴影对象没有被标记,这就意味着这些对象在结果中将不会得到合理的分割。%而且,一些对象的前景标记会一直到对象的边缘。这就意味着应该清理标记斑点的边缘,然后收缩它们。可以通过闭操作和腐蚀操作来完成。se2 = strel(ones(5,5));fgm2 = imclose(fgm, se2);fgm3 = imerode(fgm2, se2);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(Iobrcbr, []); title('基于重建的开闭操作');subplot(2, 2, 2); imshow(fgm, []); title('局部极大图像');subplot(2, 2, 3); imshow(fgm2, []); title('闭操作');subplot(2, 2, 4); imshow(fgm3, []); title('腐蚀操作');%% 这个过程将会留下一些偏离的孤立像素,应该移除它们。%可以使用bwareaopen,用来移除少于特定像素个数的斑点。BW2 = bwareaopen(BW,P)从二值图像中移除所以少于P像素值的连通块,得到另外的二值图像BW2。fgm4 = bwareaopen(fgm3, 20);It1 = rgb(:, :, 1);It2 = rgb(:, :, 2);It3 = rgb(:, :, 3);It1(fgm4) = 255; It2(fgm4) = 0; It3(fgm4) = 0;I3 = cat(3, It1, It2, It3);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(I2, []); title('局部极大叠加到原图像');subplot(2, 2, 2); imshow(fgm3, []); title('闭腐蚀操作');subplot(2, 2, 3); imshow(fgm4, []); title('去除小斑点操作');subplot(2, 2, 4); imshow(I3, []); title('修改局部极大叠加到原图像');%% 第4步:计算背景标记%现在,需要标记背景。在清理后的图像Iobrcbr中,暗像素属于背景,所以可以从阈值操作开始。bw = im2bw(Iobrcbr, graythresh(Iobrcbr));figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(Iobrcbr, []); title('基于重建的开闭操作');subplot(1, 2, 2); imshow(bw, []); title('阈值分割');%%背景像素在黑色区域,但是理想情形下,不必要求背景标记太接近于要分割的对象边缘。%%通过计算“骨架影响范围”来“细化”背景,或者SKIZ,bw的前景。这个可以通过计算bw的距离变换的分水岭变换来实现,然后寻找结果的分水岭脊线(DL==0)。%%D=bwdist(BW)计算二值图像BW的欧几里得矩阵。对BW的每一个像素,距离变换指定像素和最近的BW非零像素的距离。%%bwdist默认使用欧几里得距离公式。BW可以由任意维数,D与BW有同样的大小。D = bwdist(bw);DL = watershed(D);bgm = DL == 0;figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(Iobrcbr, []); title('基于重建的开闭操作');subplot(2, 2, 2); imshow(bw, []); title('阈值分割');subplot(2, 2, 3); imshow(label2rgb(DL), []); title('分水岭变换示意图');subplot(2, 2, 4); imshow(bgm, []); title('分水岭变换脊线图');%% 第5步:计算分割函数的分水岭变换gradmag2 = imimposemin(gradmag, bgm | fgm4);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(2, 2, 1); imshow(bgm, []); title('分水岭变换脊线图');subplot(2, 2, 2); imshow(fgm4, []); title('前景标记');subplot(2, 2, 3); imshow(gradmag, []); title('梯度幅值图像');subplot(2, 2, 4); imshow(gradmag2, []); title('修改梯度幅值图像');%% 最后,可以做基于分水岭的图像分割计算。第6步:查看结果It1 = rgb(:, :, 1);It2 = rgb(:, :, 2);It3 = rgb(:, :, 3);fgm5 = imdilate(L == 0, ones(3, 3)) | bgm | fgm4;It1(fgm5) = 255; It2(fgm5) = 0; It3(fgm5) = 0;I4 = cat(3, It1, It2, It3);figure('units', 'normalized', 'position', [0 0 1 1]);subplot(1, 2, 1); imshow(rgb, []); title('原图像');subplot(1, 2, 2); imshow(I4, []); title('标记和对象边缘叠加到原图像');
以上四种方法,虽然都只是浅尝辄止,但是处理我遇到的问题,利用最现成的方法,都不能够有很好的效果。我期望的是,有没有现成的,可以直接用到的方法呢?找了很久找不到。我又是新手,对图像处理完全不懂,最近才入行,想了好久,我想出了另外一种方法,我把它叫做旋转切割法。
旋转切割法
这个方法对于只有两个骰子连在一起的图片可以很好的分割开来。原理其实很简单。我介绍一下怎么来的。
最开始,我对没有分割开的骰子进行了细致的总结分析,发现两个骰子连在一起的图片基本上都有一个中心点,中心点基本上都在图片的中央位置。如果我以这个中心点为端点,引一条直线,旋转360度扫描每一个角度,如果那个角度上面黑色像素比重最大,那么证明我应该沿着这条线切割。然后找另外一条同样的线,只不过要夹角大于90度。
想法很美好,但是实现之后发现不行。因为图片作为一个矩阵,坐标只可能是整数,在某些角度,你会在分割的线上找不到任何像素。这种情况还比较多。
请看代码:
clear all;close all;img=imread('stackdice/161221S011172.jpg-1.jpg');img=im2bw(img);figure;imshow(img,[]);s_x=1;s_y=1;[m,n] = size(img);d=ceil(sqrt(m^2+n^2));%直径new_matrix = zeros(d,d);T2 = [1,0,0;0,1,0;-m/2,-n/2,1]; %x、y轴平移值原点T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移T4 = [1,0,0;0,1,0;-(d/2+m),-(d/2+n),1]; %x、y轴反平移T5 = [1,0,0;0,1,0;(d-m)/2,(d-n)/2,1]; %x、y轴反平移T1 = [s_x,0,0;0,s_y,0;0,0,1]; %对应的比例系数矩阵%T = T2*T1*T3; %P_new = P_old*T2*T1*T3 顺序不能错了T = T4*T5; %P_new = P_old*T2*T1*T3 顺序不能错了for i=1:d for j=1:d p = floor([i,j,1]*T5^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1) if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围 new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系 else new_matrix(i,j) = 0; %没有的点赋值为0 end endend%%以上获取新的图片 图片周围加了一圈center_x=d/2;center_y=d/2;%中心坐标figure;imshow(new_matrix,[]);hold on;pointGroup=[center_x center_y;d d/2];% 初始位置angleGroup=(0:pi/4:2*pi);init_line_value = cell(d/2);for i=1:length(angleGroup) theat=angleGroup(i); pointGroup(2,1)=ceil((cos(theat)+1)*d/2); pointGroup(2,2)=ceil((sin(theat)+1)*d/2); plot(pointGroup(:,1),pointGroup(:,2),'.-','Color',[(0.7+0.1/i)^2 1-(0.05*i) 0.5/i^2]); if pointGroup(2,1)==0 pointGroup(2,1)=1 end if pointGroup(2,2)==0 pointGroup(2,2)=1 end pointGroup A=pointGroup(1,:);%A 点 B=pointGroup(2,:); if B(1)-A(1)==0 if A(2)-B(2)>0 tmpl= new_matrix(A(1),B(2):A(2)); init_line_value{i,1:length(tmpl)}=tmpl; else tmpl= new_matrix(A(1),B(2):A(2)); init_line_value{i,1:length(tmpl)}= new_matrix(A(1),A(2):B(2)); end continue; end if B(2)-A(2)==0 if A(1)-B(1)<0 tmpl= new_matrix(A(1):B(1),A(1)); init_line_value{i,1:length(tmpl)}=tmpl; else tmpl= new_matrix(B(1):A(1),A(1)); init_line_value{i,1:length(tmpl)}=tmpl; end continue; end k=(B(2)-A(2))/(B(1)-A(1)); %k是系数; b=A(2)-k*A(1);%b是常数。(方程:y=k*x+b)。 %旋转的四种情况 if pointGroup(2,1)>=d/2 && pointGroup(2,2)>=d/2 kkaa=1; for kk1=d/2:pointGroup(2,1) init_line_value{i,kkaa}=new_matrix(kk1,ceil(k*kk1+b)); kkaa=kkaa+1; end end if pointGroup(2,1)<d/2 && pointGroup(2,2)>d/2 kkaa=1; for kk1=pointGroup(2,1):d/2 init_line_value{i,kkaa}=new_matrix(kk1,ceil(k*kk1+b)); kkaa=kkaa+1; end end if pointGroup(2,1)>d/2 && pointGroup(2,2)<d/2 kkaa=1; for kk1=d/2:pointGroup(2,1) init_line_value{i,kkaa}=new_matrix(kk1,ceil(k*kk1+b)); kkaa=kkaa+1; end end if pointGroup(2,1)<d/2 && pointGroup(2,2)<d/2 kkaa=1; for kk1=pointGroup(2,1):d/2 init_line_value{i,kkaa}=new_matrix(kk1,ceil(k*kk1+b)); kkaa=kkaa+1; end end end
那么,既然选择线不行,就只能旋转整个图像了。为什么我会首先考虑线呢?矩阵旋转和向量旋转,自然是向量运算量小很多。果不其然,换为整个图片旋转,然后固定在水平位置采样之后,执行时间慢了好多。
clear all;close all;img=imread('stackdice/161221S011161.jpg-2.jpg');img=im2bw(img);s_x=1;s_y=1;[m,n] = size(img);d=ceil(floor(sqrt(m^2+n^2)));%直径if mod(d,2)~=0 d=d+1;endnew_matrix = zeros(d,d);T2 = [1,0,0;0,1,0;-m/2,-n/2,1]; %x、y轴平移值原点T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移T4 = [1,0,0;0,1,0;-(d/2+m),-(d/2+n),1]; %x、y轴反平移T5 = [1,0,0;0,1,0;(d-m)/2,(d-n)/2,1]; %x、y轴反平移T1 = [s_x,0,0;0,s_y,0;0,0,1]; %对应的比例系数矩阵%T = T2*T1*T3; %P_new = P_old*T2*T1*T3 顺序不能错了T = T4*T5; %P_new = P_old*T2*T1*T3 顺序不能错了for i=1:d for j=1:d p = floor([i,j,1]*T5^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1) if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围 new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系 else new_matrix(i,j) = 0; %没有的点赋值为0 end endend%%以上获取新的图片 图片周围加了一圈center_x=d/2;center_y=d/2;%中心坐标figure;imshow(new_matrix,[]);hold on;pointGroup=[center_x center_y;d d/2];% 初始位置angleGroup=(0:pi/4:2*pi);for i=1:length(angleGroup) theat=angleGroup(i); pointGroup(2,1)=ceil((cos(theat)+1)*d/2); pointGroup(2,2)=ceil((sin(theat)+1)*d/2); plot(pointGroup(:,1),pointGroup(:,2),'.-','Color',[(0.7+0.1/i)^2 1-(0.05*i) 0.5/i^2]); endfor i222=1:length(angleGroup) theat=angleGroup(i222); newroate= RotateFunction(new_matrix,theat); x1_pix(:,:,i222)=newroate(d/2,d/2:d); x2_pix(:,:,i222)=newroate(d/2,1:d/2); endmax=0;max_index=0;for i=1:length(x1_pix(1,1,:)) tmp= length(find(x1_pix(:,:,i)==0)); tmp_rate = tmp/length(x1_pix(:,:,i)); if tmp_rate>max max=tmp_rate; max_index=angleGroup(i); endendfor i=1:length(x2_pix(1,1,:)) tmp= length(find(x2_pix(:,:,i)==0)); tmp_rate = tmp/length(x2_pix(:,:,i)); if tmp_rate>max max=tmp_rate; max_index=angleGroup(i); endendnewroate_final= RotateFunction(new_matrix,max_index);img1=newroate_final(1:d/2,1:d);img2=newroate_final(d/2:d,1:d);figure;imshow(img1,[]);figure;imshow(img2,[]);
无论怎样,先将就用一下把。对于三个骰子连在一起的我暂时还没有好的方法。但是目前看来,我的设计足够我们在正式的生产环境中使用了。
下图就是我通过这种方法分割的效果:
总结:
总的来说,试了很多很多方法,也许对其他的算法了解不深入,所以没有很好的结果,但是,最适合的,就是最好的。
- 骰子点数识别之图像分割
- 骰子点数识别之图像分割
- 利用神经网络识别骰子点数
- 利用卷积神经网络识别骰子点数
- 剑指Offer之 - n个骰子的点数
- 骰子点数的概率
- 输出骰子点数
- 骰子点数问题
- n个骰子的点数
- n 个骰子的点数
- n个骰子的点数
- n个骰子的点数
- n个骰子的点数
- N个骰子的点数
- n个骰子的点数
- n个骰子的点数
- n个骰子的点数
- n个骰子的点数
- OpenGL 显示DICOM医学图像
- Webpack、Browserify和Gulp
- 网络框架的简单封装
- 【Android】ListView、RecyclerView、ScrollView里嵌套ListView 相对优雅的解决方案:NestFullListView
- 【转】并发场景下的中断处理
- 骰子点数识别之图像分割
- Java super关键字
- 【java】java集合list与set、map集合的区别、用法详解
- Leetcode 22. Generate Parentheses
- 计算机视觉基础(三)——对极几何中的基本矩阵F和本质矩阵E
- Force.com Apexの「Describe」でできること
- Java集合类型详解
- 学习Laravel中创建数据表命令引发的对闭包的学习
- Servlet获取表单数据