2018-09-04 17:14:27 sy20173081277 阅读数 1598

       基于图像处理的目标数量的自动计数方法可以对采集到的图像进行处理来实现自动计数,也可以先用采集到的图像减去背景图像从而得到一个差值图像,然后对差值图像进行处理实现计数。无论哪种方式,都需要首先进行目标和背景的分割,并将分割出来的前景进行粘连分割处理,计数的精确度也受到这一过程重要的影响。

        图像分割方法大致可以分为:基于区域的分割方法侧重于利用区域内特征的相似性;基于边缘检测的分割方法利用在区域边缘上的像素灰度值的变化比较剧烈这一实际来解决图像分割问题;区域与边缘检测相结合的分割方法;基于神经网络的分割方法利用神经网络在细粒度特征提取方面的优势,可以挖掘图像本身深层次的细节特征从而更好地分割图像;基于模糊集理论的分割方法包括模糊阈值分割方法、模糊聚类分割方法和模糊连接度分割方法等。

         在进行分割之前,关于彩色图像和灰度图像的处理,一般如果原始图像为彩色图像则转化为灰度二值图像,然后在进行分割处理,如果是灰度图则可以直接利用上述的方法进行分割处理。

         关于图像计数方面,国内外都进行了大量的研究,比较常见的有,细化法,连通域法,像素点分布法等

2018-04-18 00:16:43 u010030977 阅读数 3796

存在接壤现象的细胞计数

因为前面(一)的中的图片每个波点之间间隔较小,这边的细胞图中存在多个目标接壤问题,所以怎样在存在接壤现象的细胞中准确数出个数是这里较前面不同的地方。

解决思路:

  • 进行锐化和平滑滤波操作
  • 根据灰度图进行阈值分割
  • 形态学处理
  • 分水岭算法
  • 修正

如果使用Python,可以选择的图像处理库有
1、工业级的图像处理库:Opencv
2、PIL
3、Skimage
我使用的是Skimage,因为它和numpy联和的比较紧密,使用较为方便,能暂时满足我基本需求。

进行锐化和平滑滤波操作

我选取的图片是一张细胞图,背景和前景的照片亮度信息差别很大,因此只需要根据灰度值,来进行前景和背景的分离。

# 锐化+平滑滤波操作
img_path1 = '细菌图.jpg'

from PIL import Image, ImageFilter
im = Image.open(img_path1)
# 没找到skimage的锐化api...所以用了PIL的
im.filter(ImageFilter.SHARPEN).save('细菌图_temp.jpg')

sharpen_data = io.imread('细菌图_temp.jpg')
img = color.rgb2gray(sharpen_data)
dst = median_each(img)

plt.figure('filters',figsize=(14,14))

plt.subplot(121)
plt.title('origin image')
orgin_img = io.imread(img_path1)
plt.imshow(orgin_img)

plt.subplot(122)
plt.title('sharpen and Smoothed image')
plt.imshow(dst,plt.cm.gray)

这里写图片描述

根据灰度图进行阈值分割

# 直方图信息
plt.figure("hist")
arr=dst.flatten()
plt.hist(arr, bins=256, normed=1,facecolor='b',edgecolor='b',hold=1)
plt.show()

这里写图片描述

# 手动查看鼠标对应H值
%matplotlib qt5
loop_num = 5
plt.imshow(dst,plt.cm.gray)

pos=plt.ginput(loop_num)
for i in range(loop_num):
    x,y = int(pos[i][1]),int(pos[i][0])
    print '第%d个点击的 x,y:' % int(i+1) ,'(', x , y,')'
    print '对应的灰度值为:',dst[x,y],'\n'

这里写图片描述

# 手动选取阈值
%matplotlib inline
rows,cols=dst.shape
labels=np.zeros([rows,cols])
for i in range(rows):
    for j in range(cols):
        if(dst[i,j] < 135):
            labels[i,j]=1
        else:
            labels[i,j]=0
io.imshow(labels)

这里写图片描述

形态学处理

先膨胀填充孔洞,然后进行开操作去除孤立的小点

# 膨胀,开操作
labels= sm.dilation(labels,sm.square(3))
labels = sm.opening(labels,sm.disk(5))

分水岭算法

偶然发现了分水岭算法,它是一种基于区域的图像分割算法,很适合把这里的接壤细胞区分开来。在分水岭算法第一步会使用一个关键的api——peak_local_max,他可以找到局部的“山峰”,相当于找到了我们要找的细胞的中心!
分水岭算法也在skimage的形态学包里,具体的使用可以查看官网。

from scipy import ndimage as ndi
# labels = dst
distance = ndi.distance_transform_edt(labels) #距离变换
# min_distance:最小的像素在2×min_distance + 1区分离(即峰峰数至少min_distance分隔)。找到峰值的最大数量,使用min_distance = 1。
# exclude_border:不排除峰值在图像的边界
# indices:False会返回和数组相同大小的布尔数组,为True时,会返回峰值的坐标
local_maxi =feature.peak_local_max(distance, exclude_border = 0,min_distance = 12,indices=False,
                                   footprint=np.ones((10, 10)),labels=labels) #寻找峰值
markers = ndi.label(local_maxi)[0] #初始标记点
label_ =morphology.watershed(-distance, markers, mask=labels) #基于距离变换的分水岭算法

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))
axes = axes.ravel()
ax0, ax1, ax2, ax3 = axes

ax0.imshow(labels, cmap=plt.cm.gray)#, interpolation='nearest')
ax0.set_title("Original")
ax1.imshow(-distance, cmap=plt.cm.jet, interpolation='nearest')
ax1.set_title("Distance")
ax2.imshow(sm.dilation(markers,sm.square(10)), cmap=plt.cm.spectral, interpolation='nearest')
ax2.set_title("Markers")
ax3.imshow(label_, cmap=plt.cm.spectral, interpolation='nearest')
ax3.set_title("Segmented")

for ax in axes:
    ax.axis('off')

fig.tight_layout()
plt.show()

这里写图片描述

修正

可能是参数没有调好,我发现了很多找出的“峰值”靠的很近(8领域内)。我使用欧式距离剔除了选出的重复点。

# 修正
import math
err = []
for i in range(x_y.shape[0]):
    h1,w1 =  x_y[i][0],x_y[i][1]
    if i in err:
        continue
    for j in range(i+1,x_y.shape[0]):
        h2,w2 =  x_y[j][0],x_y[j][1]
        ab = math.sqrt(math.pow(abs(h2-h1), 2) + math.pow(abs(w2-w1), 2))
        if ab <= 10:
#             print 'error:' , x_y[i],' and ', x_y[j],'i,j = ',i,j
            err.append(j)
new_x_y = []
for i in range(len(x_y)):
    if i not in err:
        new_x_y.append(x_y[i])
print '一共有',len(new_x_y),'个圈'

这里写图片描述


本思路在钢筋图像上的效果:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


总结

其实从这几张测试结果图可以看出这个算法存在的问题,因为核心是通过直方图的阈值分割来进行前景背景的分离。在面对这种比较现实的图像时背景比较复杂,因此对背景的识别很混乱。而且现实图片多变,需要调试的参数和优化的地方还有很多。可行改进方案是进行感兴趣区域提取,在这个区域进行统计。当然这里介绍的整个方法基于数字图像处理,并没有识别的步骤,要完成计数也可以采用机器学习的监督学习。

2018-04-23 21:39:55 simon_family 阅读数 18319

代码戳这里

 

1. 实验内容

 

本实验为使用MATLAB编写的细胞图像分割及计数系统,实现了对图像内细胞的计数,以及对每个细胞周长和面积的测量,并分别展示了分割后的每个细胞的图像。

实验步骤共分为图像预处理、图像预分割、空洞填充、黏连细胞分割、细胞个数统计、细胞特征统计及显示。

实验所用图像如下图所示:

2. 图像预处理

 

使用滤波对细胞图像进行保边去噪的处理,这步的主要作用是去除图像噪声,系统中提供了中值滤波、均值滤波、维纳滤波、锐化滤波,经过测试发现中值滤波的效果最好,因此以中值滤波为例进行下面的实验。

部分代码如下:

global original_img show_img;
str=get(hObject,'string');
axes(handles.axes1);
[m,n,k]=size(original_img);
switch str
    case '原图'
        show_img=original_img;
        imshow(show_img);
    case '中值滤波'  
        show_img=original_img;
        for i=1:3
            show_img(:,:,i)=medfilt2(show_img(:,:,i));
        end
        imshow(show_img);
    case '均值滤波'
        show_img=original_img;
        h=ones(3,3)/9;
        for i=1:3
            show_img(:,:,i)=imfilter(show_img(:,:,i),h);
        end
        imshow(show_img);
    case '维纳滤波'
        show_img=original_img;
        for i=1:3
            show_img(:,:,i)=wiener2(show_img(:,:,i),[5 5]);
        end
        imshow(show_img);
    case '锐化滤波'
        show_img=original_img;
        h=[0 1 0;1 -4 1;0 1 0];
        for i=1:3
            J=conv2(im2double(show_img(:,:,i)),h,'same');
            show_img(:,:,i)=show_img(:,:,i)-uint8(J);
        end
        imshow(show_img);  
end

中值滤波图像如下:

3. 预分割

选择彩色细胞图像的蓝色通道,并对该通道的灰度图,用大津法Otsu进行二值化预分割,将细胞作为前景分割出来。

global show_img;
B=show_img(:,:,3);
B_gray=im2double(B);
level=graythresh(B_gray);
B_bw=im2bw(B_gray,level);
axes(handles.axes1);
show_img=B_bw;
imshow(show_img);

预分割图像如下:

4. 孔洞填充

对分割后的二值图,实施开运算,填充细胞中的孔洞,使轻微粘连细胞分开及细小的细胞消失。

global show_img;
se=strel('disk',5);
Spot_filled=imopen(show_img,se);
axes(handles.axes1);
show_img=Spot_filled;
imshow(show_img);

填充孔洞后的图像如下:

5. 黏连细胞分割

使用分水岭分割,将图像中粘连严重的细胞分割开来,对于仍难以分离的细胞,使用手动分割,用鼠标作为笔,将划过的像素点的值设为0,鼠标松开后,再进行一次分水岭分割。

分水岭分割代码:

global show_img;
D=-bwdist(~show_img);
mask=imextendedmin(D,2);
D2=imimposemin(D,mask);
Ld=watershed(D2);
Water_splited=show_img;
Water_splited(Ld==0)=0;
axes(handles.axes1);
show_img=Water_splited;
imshow(show_img);

手动分割代码:
 

global ButtonDown  show_img;  
if ButtonDown == 1  
    pos = get(handles.axes1, 'CurrentPoint');
    row=floor(pos(1,2));
    col=floor(pos(1,1));
    Diy_splited=show_img;
    Diy_splited(row,col)=0;
    show_img=Diy_splited;
    axes(handles.axes1);
    imshow(show_img);
end  

分割后的图像如下:

6. 细胞个数统计及显示

首先删除掉边缘上的细胞,再利用四连通区域标记算法统计分割后非粘连细胞的个数,最后在原图上标记出分割好的细胞,并标号。

细胞个数统计代码:

global N show_img original_img img_group perimeter_group area_group;
[B,L,N]=bwboundaries(show_img,'noholes');
[m,n]=size(show_img);
counted_img=zeros(m,n);
for i=1:N
    %显示边缘
    for j=1:size(B{i},1)
        counted_img(B{i}(j,1),B{i}(j,2))=1;
    end
    %标号
    med_row=floor(mean(B{i}(:,1)));
    med_col=floor(mean(B{i}(:,2)));
    if floor(i/10)==0
        str=[num2str(i) '.png'];
        I=imread(str);
    else
        str1=[num2str(floor(i/10)) '.png'];
        str2=[num2str(rem(i,10)) '.png'];
        I1=imread(str1);
        I2=imread(str2);
        I=[I1 I2];
    end
    [number_row,number_col]=size(I);
    counted_img((med_row - (number_row/2)):(med_row + (number_row/2) - 1),(med_col - (number_col/2)):(med_col + (number_col/2) - 1))=I;
    %截取每个细胞图像
    item_img=original_img(med_row - 45:med_row +44,med_col - 45:med_col + 44,:);
    item_img_index=L(med_row - 45:med_row +44,med_col - 45:med_col + 44);
    index=find(item_img_index~=i);
    r=item_img(:,:,1);
    g=item_img(:,:,2);
    b=item_img(:,:,3);
    r(index)=255;
    g(index)=255;
    b(index)=255;
    item_img=cat(3,r,g,b);
    img_group{i}=item_img;
    %每个细胞周长
    item_perimeter=size(B{i},1);
    perimeter_group{i}=item_perimeter;
    %每个细胞面积
    item_area=length(find(L==i));
    area_group{i}=item_area;
end

原图细胞标号代码:

R=original_img(:,:,1)+uint8(counted_img*255);
G=original_img(:,:,2)+uint8(counted_img*255);
B=original_img(:,:,3)+uint8(counted_img*255);
show_img=cat(3,R,G,B);
axes(handles.axes1);
imshow(show_img);

统计结果图如下:

7. 细胞特征统计与显示

对每个细胞,统计其面积,并用提取细胞边缘,统计边缘轮廓上的像素个数即细胞周长,将每个细胞的图像及相关信息分别显示出来。

global N img_group perimeter_group area_group page pages;
page=1;
pages=ceil(N/6);
str=['第' num2str(page) '/' num2str(pages) '页'];
set(handles.page_num,'string',str);
if page~=pages
    axes(handles.item1);imshow(img_group{1});
    axes(handles.item2);imshow(img_group{2});
    axes(handles.item3);imshow(img_group{3});
    axes(handles.item4);imshow(img_group{4});
    axes(handles.item5);imshow(img_group{5});
    axes(handles.item6);imshow(img_group{6});
    for i=1:6
        strs{i}=['No.' num2str(i) ' ' '周长:' num2str(perimeter_group{i}) ' ' '面积:' num2str(area_group{i})];
    end
    set(handles.detail_info1,'string',strs{1});
    set(handles.detail_info2,'string',strs{2});
    set(handles.detail_info3,'string',strs{3});
    set(handles.detail_info4,'string',strs{4});
    set(handles.detail_info5,'string',strs{5});
    set(handles.detail_info6,'string',strs{6});
else
    item_img=ones(size(img_group{1}));
    item_img(:,:,:)=255;
    item_imgs{1:6}=item_img;
    item_strs{1:6}='';
    for i=1:N
        item_imgs{i}=img_group{i};
        item_strs{i}=['No.' num2str(i) '   ' '周长:' num2str(perimeter_group{i}) '   ' '面积:' num2str(area_group{i})];
    end
    axes(handles.item1);imshow(item_imgs{1});
    axes(handles.item2);imshow(item_imgs{2});
    axes(handles.item3);imshow(item_imgs{3});
    axes(handles.item4);imshow(item_imgs{4});
    axes(handles.item5);imshow(item_imgs{5});
    axes(handles.item6);imshow(item_imgs{6});
    
    set(handles.detail_info1,'string',item_strs{1});
    set(handles.detail_info2,'string',item_strs{2});
    set(handles.detail_info3,'string',item_strs{3});
    set(handles.detail_info4,'string',item_strs{4});
    set(handles.detail_info5,'string',item_strs{5});
    set(handles.detail_info6,'string',item_strs{6});
end

分页显示结果如下:

8. 实验心得

本次实验耗时3天完成,实现了实验要求的所有功能,但由于时间仓促,仍有不少细节地方需要完善。在实验过程中,有一些功能在代码实现上比较有难度,所幸最终找到了解决办法,以下是我认为在编码实现过程中遇到的最有难度的三个问题及详细解决办法。

(1)手动分割

使用分水岭分割后,仍有细胞没有被分割开,需要进行手动分割。方法为通过GUI鼠标响应,当鼠标按下和移动时,获取当前光标所在像素的横纵坐标,将图像中对应位置处的数值改为0,再显示新的图像。在鼠标移动过程中,对图像的修改速度远远小于鼠标滑动速度,这样只会在鼠标划过的路径上面留下一些黑点,而不是一条线。在鼠标松开时,对图像再进行一次分水岭分割,就会沿着黑点的路径生成一条分割线,从而实现对黏连严重细胞的手动分割。

(2)原图细胞标号

首先通过绘图软件作出0到9共10个数字的图像,使用MATLAB处理得到每个数字的二值图用于之后的标号。通过bwboundaries对图像进行标记后,得到每个细胞的边缘像素点的横纵坐标,再计算得出每个细胞的中心位置坐标,将该坐标与对应数字图像的中心坐标对应,将数字图像加到原图上,从而实现对原图细胞的标号。对于标号是两位数的细胞,需首先将十位上的数字和各位上的数字拼接,生成新的图像用于标号。

(3)结果分页显示

由于对GUI对象的操作无法通过循环结构实现,因此首先生成6张全白的图像,再根据这一页上要显示的细胞个数,对相应的图像进行修改,最后将这6张图像全部显示出来,是细胞图像的就显示细胞图像,不是细胞图像的则显示全白的图像。

 

 

2019-03-26 15:04:29 weixin_40920848 阅读数 1352

以前没有关注这方面的内容,因为本身与医学也相差万里。总是不理解为什么女朋友每天实验会那么辛苦,原来会经常数数以万计的细胞。大致了解了下一般采用的是PS、Image J等手段来进行细胞计数,但也都会出现不同程度的误差。所以就想着从图像处理的角度去尝试下,网上也已经有一些相关的利用MATLAB编写的代码。

一般来说利用图像处理的手段可以分为以下几个步骤:

  1. 图像格式的转换,及RGB图像转化为GRAY图像,这步大家都了解的;
  2. 然后进行图像的分割,中间会利用一些形态学处理方式,主要思想就是先进行膨胀扩大细胞边缘,然后进行腐蚀取反以确定细胞核的位置,之后采用分水岭算法将连接的细胞分割开;
  3. 对图像进行高斯滤波使图像变得模糊,细胞核相对于细胞边缘颜色较深,突出显示细胞核位置;
  4. 对图像进行锐化获得细胞的轮廓位置信息并进行边沿去除操作;
  5. 通过中值滤波之后对检测到的细胞进行编号。

 

用上面两幅图验证了下,结果还不错,具体是什么细胞我也不是很清楚。中间会有几个参数对结果有一定的影响,图像分割时的灰度阈值由大津法产生,高斯滤波是sigma设为3,其中对最终结果影响最大的是中值滤波的模板大小,通常情况下设置为13较为合理,可以适当的根据图像中细胞数量的多少进行调节。排列较密集时可以适当降低模板大小,对于细胞中心部分和边沿部分变现差异很小且散布集中的细胞处理有一定的难度。班门弄斧了,希望大家指点吐槽,但不接受人身攻击。

clc;close all;clear all;
origin_img=imread('C:\Users\Administrator\Desktop\大黄\1.png'); 
subplot(2,3,1);imshow(origin_img);title('原始图像');
[m,n]=size(origin_img);
img=rgb2gray(origin_img);%灰度
B=origin_img(:,:,3);
B_gray=im2double(B);
level=graythresh(B_gray);
B_bw=im2bw(B_gray,level);
show_img1=B_bw;
subplot(2,3,2);imshow(show_img1);title('灰度图像');
D=-bwdist(~show_img1);
mask=imextendedmin(D,2);
D2=imimposemin(D,mask);
Ld=watershed(D2);
Water_splited=show_img1;
Water_splited(Ld==0)=0;
show_img1=Water_splited;
subplot(2,3,3);imshow(show_img1);title('分割后图像');
sigma=3;
gausFilter=fspecial('gaussian',[5,5],sigma);
Mod=imfilter(img,gausFilter,'replicate');%高斯滤波
subplot(2,3,4);imshow(Mod);title('模糊图像');
lamda=1;
img2=(img-lamda*Mod)/(1-lamda);
subplot(2,3,5);imshow(uint8(img2));title('锐化后图像');%锐化后图像
img3=imclearborder(img2,8);
subplot(2,3,6);imshow(uint8(img3));title('去除边缘图像');%锐化后图像
% % BW = imregionalmin(img3,8);%最小连通区域
% P=BW+5;
% % img4 = bwareaopen(img3,P,8);%删除小于P后的图像
% imwrite(uint8(img2),'leansharpe.jpg');
K=imnoise(img3,'salt & pepper',0.005);%加入椒盐噪声
n2=12;%中值滤波的模板的大小
I=im2bw(K);
Y3=medfilt2(K,[n2 n2]); %调用系统函数进行中值滤波,n2为模板大小 
[L,num] = bwlabel(Y3,8);
STATS1=regionprops(L,'Perimeter'); 
ahe=size(STATS1);
figure(2);imshow(origin_img);
m1=ahe(1,1);
m=zeros(2,m1); 
for i=1:m1
  % 计算目标区域中心,用于显示编号的位置
  [p,q]=find(L==i);
  temp=[p,q];   
  [x,y]=size(temp);
  m(1,i)=sum(p)/x;
  m(2,i)=sum(q)/x;
end
for i=1:m1
  figure(2);
  text(m(2,i),m(1,i),int2str(i),'FontSize',12,'color','red','LineWidth',10)
end
num

 

 

 

 

 

 

2016-08-01 20:48:41 Small_Mouse0 阅读数 8981

java图像处理之图的联通计数
图的联通分量计数,根据连通区域可分为八连通和四连通
(1)八连通:上左,上,上右,左,右,下左,下,下右
1 1 1
1 0 1
1 1 1 0和周围的1都视为连通关系
(2)四连通:上,下,左,右
2 1 2
1 0 1
2 1 2 0仅和周围的1连通,和二视为不连通

主要思路如下

图像的联通分量计算,
使用递归算法,首先创建一个二维的的数组,用于存放二进制的图像数据,
(1)起初白色为1,黑色为0, 用for循环去遍历图像,横向扫描,由于图像已经使用腐蚀算法去除了细小的杂质和,简单的分离了白色区域,对其连通区域进行标记为 n
(2)标记逻辑为:
使用递归算法,对其周围四个进行访问,(四连通)直至周围没有1,遇到联通的可以标记为同一个数字。
使用递归算法,对其周围八个进行访问,(八连通)直至周围没有1,遇到联通的可以标记为同一个数字。

源码如下:

八连通和四连通算法及UI测试代码实现如下

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class bwlable extends JPanel{

    int image[][];
    BufferedImage grayImage;
    BufferedImage colorImage;
    int counter=1;

    public bwlable(int[][] grayImageData) {
        // TODO Auto-generated constructor stub

        image = new int[grayImageData.length][grayImageData[1].length];
        for (int i = 1; i < grayImageData.length-1; i++) {
            for (int j = 1; j < grayImageData[0].length-1; j++) {
                image[i][j] = grayImageData[i][j];
            }
        }
        for (int i = 1; i < grayImageData.length-1; i++) {
            for (int j = 1; j < grayImageData[0].length-1; j++) {
                if (image[i][j] == 1) {
                    counter++;
                    dealBwlabe(i,j);
                }
            }
        }
        System.out.println(counter-1);

        color();
        dialog();

    }

    private void dealBwlabe(int i, int j) {
        // TODO Auto-generated method stub
        //上
        if (image[i-1][j] == 1) {
            image[i-1][j] = counter;
            dealBwlabe(i-1, j);
        }
        //左
        if (image[i][j-1] == 1) {
            image[i][j-1] = counter;
            dealBwlabe(i, j-1);
        }
        //下
        if (image[i+1][j] == 1) {
            image[i+1][j] = counter;
            dealBwlabe(i+1, j);
        }
        //右
        if (image[i][j+1] == 1) {
            image[i][j+1] = counter;
            dealBwlabe(i, j+1);
        }

////八连通需要
//      //上左
//      if (image[i-1][j-1] == 1) {
//          image[i-1][j-1] = counter;
//          dealBwlabe(i-1, j-1);
//      }
//      //上右
//      if (image[i-1][j+1] == 1) {
//          image[i-1][j+1] = counter;
//          dealBwlabe(i-1, j+1);
//      }
//      //下左
//      if (image[i+1][j-1] == 1) {
//          image[i+1][j-1] = counter;
//          dealBwlabe(i+1, j-1);
//      }
//      //下右
//      if (image[i+1][j+1] == 1) {
//          image[i+1][j+1] = counter;
//          dealBwlabe(i+1, j+1);
//      }       

    }

    private void color(){

        int color[];
        color = new int[counter+1];

        for (int i = 0; i < color.length; i++)  
            color[i] = (int) (0xff000000+Math.random()*0xffffff);
        colorImage = new BufferedImage(image.length, image[0].length, 5);

        for (int i = 0; i < colorImage.getWidth(); i++) 
            for (int j = 0; j < colorImage.getHeight(); j++) 
            {   if (image[i][j] > 0) colorImage.setRGB(i, j, color[image[i][j]]);
                else colorImage.setRGB(i, j, 0xff000000);
            }

    }

    public void dialog(){
        JFrame mFrame = new JFrame();
        mFrame.setSize(800, 500);
        mFrame.setVisible(true);

        mFrame.add(this);
        //mFrame
    }
    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        try {
            grayImage = ImageIO.read(new File("specialGray.jpg"));

            g.drawImage(grayImage, 0, 0, 400, 500, null);
            g.drawImage(colorImage, 402, 0, 400, 500, null);
            g.setColor(Color.red);
            Font mFont= g.getFont();
            g.setFont(new Font(mFont.getFontName(), Font.PLAIN, 20));
            g.drawString(counter-1+" ", 2, 20);
            g.drawString("原图", 100, 400);
            g.drawString("染色处理图", 500, 400);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }
}

test代码如下:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class test {

    public static void main(String[] args) throws IOException {

//      new bwlable(getCircle(10));
        BufferedImage mBufferedImage = ImageIO.read(new File("specialGray.jpg"));

        int image[][];
        image = new int[mBufferedImage.getWidth()][mBufferedImage.getHeight()];
        int numRGB = 0xff222222;
        for (int i = 0; i < image.length; i++) {
            for (int j = 0; j < image[0].length; j++) {
                if (mBufferedImage.getRGB(i, j) > numRGB)   image[i][j] = 1;
                else image[i][j] = 0;
            }
        }
        new bwlable(image);

    }

测试结果如下:
这里写图片描述

算法实现敬请参考,欢迎指点

没有更多推荐了,返回首页