基于鱼皮肤的鱼个体识别(1)

原始图像

在这里插入图片描述

鱼在水族箱里面,背景是绿色,可以很好的和背景分割。

图像分割

  1. 读取图像,转换HSV

首先了解一下这个函数和RGB HSV
HSV = rgb2hsv(RGB) converts the red, green, and blue values of an RGB image to hue, saturation, and value (HSV) values of an HSV image.
HSV image, returned as an m-by-n-by-3 numeric array with values in the range [0, 1]. The third dimension of HSV defines the hue, saturation, and value for each pixel, respectively, as described in the table.

RGB颜色空间:

 RGB(red,green,blue)颜色空间最常用的用途就是显示器系统(计算机、电视机等都是采用RGB颜色空间来进行图像显示)。一般来说,电脑,电视机等是利用三个电子枪分别发射R分量,G分量,B分量的电子束,以此来激发屏幕上的RGB三种颜色的荧光粉,从而发出不同颜色、不同亮度的像素、进而组成了一幅图像;很明显,RGB颜色空间利用了物理学中的三原色叠加从而组成产生各种不同颜色的原理。在RGB颜色空间中,R、G、B三个分量的属性是独立的。也即是说,RGB颜色可以表示为(Red, Green, Blue)。其中,各个分量的数值越小,亮度越低。数值越大,亮度越高;如:(0,0,0)表示黑色,(255,255,255)表示白色;

HSV颜色空间:

HSV(hue,saturation,value)表示色相、饱和度和亮度。该颜色空间可以用一个圆锥来表示,如下图所示:
在这里插入图片描述
在这里插入图片描述
这里,hue表示颜色的相位角,取值范围是0—360;S表示颜色的饱和度;S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率,通俗点讲,S表示的是某种颜色的“纯度”, S取值越大,表示色彩越纯,取值越小,表示色彩越灰。V表示色彩的明亮程度,范围从0到1。V等于0表示圆锥的底部定点,也就是黑色,V等于1表示圆锥的顶面,当V=1并且S=0时表示纯白色;

img1=imread('../fish_2_7_07.jpg');
imshow(img1);
i = imresize(img1,0.25);
% recalculate RGB to HSV
inewhsv= rgb2hsv(i);

在这里插入图片描述

找背景

需要用到下面函数
J = imerode(I,SE) erodes the grayscale, binary, or packed binary image I, returning the eroded image, J. SE is a structuring element object or array of structuring element objects, returned by the strel or offsetstrel functions.

% threshold for 2 channels (Hue, Value)
ib = inewhsv(:,:,2)>0.75 ;
ib = (imerode(ib,strel('disk',3)));

鱼和背景就分开了
在这里插入图片描述
现在背景还不是很好的分开,我们需要的只是鱼的部分
在这里插入图片描述
对于每一列,我们从上往下找第一个白色的像素,同时也找第一个从下往上的像素的位置,这两个像素位置之间的所有点设置为1,也就是白色。

for x = 1:size(ib,2)
    y1=-1;
    for y = 1:size(ib,1)
        if ib(y,x)==1
            y1=y;
            break;
        end
    end
    if y1>-1
        for y = size(ib,1):-1:1
            if ib(y,x)==1
                y2=y;
                break;
            end
        end
        for y = y1:y2
            ib(y,x)=1;
        end
    end
    
end

结果如下
在这里插入图片描述
拿到背景图


background(:,:,1)=inewhsv(:,:,1).*ib;
background(:,:,2)=inewhsv(:,:,2).*ib;
background(:,:,3)=inewhsv(:,:,3).*ib;

在这里插入图片描述
那么鱼就是

object = (background(:,:,2)<0.8).*ib;

在这里插入图片描述
标记联通区域,找到最大的区域

Label connected components in 2-D binary image

L = bwlabel(BW) returns the label matrix L that contains labels for the 8-connected objects found in BW.

stats = regionprops(BW,properties) returns measurements for the set of properties specified by properties for each 8-connected component (object) in the binary image, BW. stats is struct array containing a struct for each object in the image. You can use regionprops on contiguous regions and discontiguous regions (see Algorithms).

BWfish = bwlabel(object);
objectinfo = regionprops(BWfish,'Area','BoundingBox');
MaxSize = 0;
id =0;
for inew = 1:size(objectinfo,1)
    if objectinfo(inew).Area>MaxSize
        if objectinfo(inew).BoundingBox(2)>1
            MaxSize = objectinfo(inew).Area;
            id=inew;
        end
    end
end

在这里插入图片描述

读取到鱼,排除背景


objectinfo(id).BoundingBox = round(objectinfo(id).BoundingBox);
background = i(objectinfo(id).BoundingBox(2):objectinfo(id).BoundingBox(2)+(objectinfo(id).BoundingBox(4)-1),objectinfo(id).BoundingBox(1):objectinfo(id).BoundingBox(1)+(objectinfo(id).BoundingBox(3)-1),:);

在这里插入图片描述

检测角度,旋转到水平


myibobject = imclose(BWfish,strel('disk',11));
myibobject = imfill(ibobject,'holes');
    
mask = myibobject;
mask = mask(:,:,1)>0;
maskinfo = regionprops(mask,'Orientation');
background = imrotate(background, -maskinfo(1).Orientation);
mask = imrotate(mask, -maskinfo(1).Orientation);

在这里插入图片描述

去掉背景

myibobject = imclose(BWfish,strel('disk',11));
myibobject = imfill(ibobject,'holes');
mask = myibobject;
mask = uint8(mask(:,:,1)>0);

objectinfo(id).BoundingBox = round(objectinfo(id).BoundingBox);
mask_background= mask(objectinfo(id).BoundingBox(2):objectinfo(id).BoundingBox(2)+(objectinfo(id).BoundingBox(4)-1),objectinfo(id).BoundingBox(1):objectinfo(id).BoundingBox(1)+(objectinfo(id).BoundingBox(3)-1),:);

background = i(objectinfo(id).BoundingBox(2):objectinfo(id).BoundingBox(2)+(objectinfo(id).BoundingBox(4)-1),objectinfo(id).BoundingBox(1):objectinfo(id).BoundingBox(1)+(objectinfo(id).BoundingBox(3)-1),:);
background(:,:,1)=background(:,:,1).*mask_background;
background(:,:,2)=background(:,:,2).*mask_background;
background(:,:,3)=background(:,:,3).*mask_background;

在这里插入图片描述

旋转到水平

%%%%%%%%%%%%%%%%%
maskinfo = regionprops(mask,'Orientation');
background = imrotate(background, -maskinfo(1).Orientation);
mask_background = imrotate(mask_background, -maskinfo(1).Orientation);
%     imshow(background)

在这里插入图片描述

OK了

posted on 2019-11-08 04:06  MrCharles在cnblogs  阅读(272)  评论(0编辑  收藏  举报

导航