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

原始图像

在这里插入图片描述

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

图像分割

  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.bash

RGB颜色空间:svg

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时表示纯白色;ui

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.spa

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

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

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

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

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

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

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

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

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了