改变眼睛图像中特定区域的颜色[Matlab] [英] Change color of a specific region in eye image [Matlab]

查看:307
本文介绍了改变眼睛图像中特定区域的颜色[Matlab]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更改以下图片的瞳孔:




这不是特征提取或眼睛检测任务。我想手动改变瞳孔的颜色。



我尝试做的是找到瞳孔颜色值并将它们更改为红色或紫色,例如:



I2 是加载的图片:

  I3 =(I2&小于100); 
figure(5)
imagesc(I3)
colormap purple



我已经在论坛中搜索过,我没有看到任何正确的解决方案

有什么建议吗?

解决方案

不幸的是,你没有选择,只能检测瞳孔的位置,并用你想要的颜色填充这些像素。简单的阈值处理是行不通的,因为睫毛的强度分布与瞳孔大致相同。



我们可以做的是做一些后期处理 你阈值图像。但是,我建议的将需要MATLAB中的图像处理工具箱。如果你没有这个,那么不幸的是我的解决方案将不起作用。



假设你确实可以访问它,我可以建议使用选择磁盘结构元素来缩小差距。一旦我们缩小差距,我们就可以使用我们最终会显示图片。我还将瞳孔的颜色设置为红色。您可以通过将常量赋值(255,0,0)更改为您想要的颜色,将RGB值更改为您想要的任何值。



这就是我们得到的:








为了您的复制和粘贴乐趣,这是从头到尾的完整代码:

  im = imread('http://i.stack.imgur.com/d3hy5.jpg'); 
im = rgb2gray(im);
s = regionprops(im< 35,'Area','PixelList');
areas = [s.Area]。';
ind = find(= = 480);
pix = s(ind).PixelList;
mask = logical(full(稀疏(pix(:,2),pix(:,1),1,size(im,1),size(im,2))));
mask = imclose(mask,strel('disk',4,4));
mask = imfill(mask,'holes');
red = im;
red(mask)= 255;
green = im;
green(mask)= 0;
blue = im;
blue(mask)= 0;
out = cat(3,红色,绿色,蓝色);
imshow(out);


I am trying to change the pupil of the following image:

This is not a feature extraction or eye detection task. I want to "manually" change the color of the pupil.

What I tried to do is to locate the pupil color values and change them to red or purple for example:

I2 is the loaded image:

I3=(I2<100);
figure(5)
imagesc(I3) 
colormap purple


I already searched in the forum and I didn't see any proper solutions
Any suggestions?

解决方案

Unfortunately, you don't have a choice but to detect where the pupil is located and fill those pixels in with your desired colour. Simply thresholding will not work because the eyelashes have roughly the same intensity distribution as the pupil.

What we can do is do some post-processing after you threshold the image. However, what I am suggesting will require the Image Processing Toolbox in MATLAB. If you don't have this, then unfortunately my solution won't work.

Assuming that you do have access to this, what I can suggest is use regionprops to detect unique shapes in your image. This is assuming that you threshold the image properly. I'm going to specifically look at the 'Area' and 'PixelList' attributes. Once we threshold the image, we should expect predominantly two areas of clustered pixels: The eyelashes and the pupil. The eyelashes will probably have the largest amount of area while the pupil the second largest. As such, let's take a look at the Area attribute and determine the object in your image that has the second largest area. Once we find this object, we will set these pixels where this area is located to whatever colour you wish. However, we're going to have to do a bit of post-processing to ensure that the entire pupil gets filled in. You see that there is a white spot in the middle of the pupil most likely due to the flash of the camera. We would essentially need to ensure that the entire detected pupil is a closed contour, then fill in the shape. Once we fill in this shape, we simply use these pixels and set them to whatever colour you wish in the output image.


Now, the first step is to threshold the image properly. First, I read in the image directly from StackOverflow. However, this image is a RGB image, and I want the grayscale equivalent. We can use rgb2gray to accomplish that for us. Once that's done, I used a threshold of intensity 35, then ran through regionprops like so:

im = imread('http://i.stack.imgur.com/d3hy5.jpg');
im = rgb2gray(im);
s = regionprops(im < 35, 'Area', 'PixelList');

s will contain a structure of information, where each element tells you the area and the pixels that belong to each unique object that was detected in your image. Let's take a look at the area:

areas = [s.Area].'

areas =

       1
       2
       1
       2
       5
       3
       1
      19
       3
       1
       2
       2
       1
      23
    1224
       1
       2
      41
      12
       2
       1
       2
       1
       5
       2
      33
     480
       3
       6
       1
       2
       1
       1
       2
       1

You can see that there are a lot of spurious isolated pixels that result after we threshold, which makes sense. You will also see that we have a couple of patches that have a significantly larger area than the majority of the patches. There is one patch that has an area of 1433, while another 480. The area with 1433 is most likely the pixels that belong to the eyelashes, as they more or less share the same intensity distribution as that of your pupil. The pupil will lost likely be the second highest area. As such, let's take a look at the patch that has the second highest area. To figure out where this is, use find:

ind = find(areas == 480);

Now that we know where this is located in s, let's pull this out and get out the PixelList attribute. This gives you a list of pixels that belong to the object:

pix = s(ind).PixelList;

The first column denotes the column position of each pixel belonging to the object while the second column denotes the row position. What I'm going to do next is take these pixels and create a mask that only contains these detected pixels. I will use this mask to index into the original image and set those pixels to whatever colour you want. As such:

mask = logical(full(sparse(pix(:,2), pix(:,1), 1, size(im,1), size(im,2))));

The code uses sparse to create a sparse matrix where every value is 0 except for those pixel locations defined in pix. This is an easier way of creating matrix of 1s only at specified locations and 0 otherwise. Because this is sparse, I need to change this to a full numeric matrix that we can use, and we finally need to cast using logical to ensure a proper mask.

If we show this mask using imshow, this is what we get:

You can see that there is a gap due to the white spot of the pupil in the original image, which makes sense. You will also notice that the contour of the pupil isn't entirely closed. As such, I'm going to perform morphological closing by imclose by choosing a disk structuring element to close the gaps. Once we close the gaps, we can use imfill and choose the 'holes' flag to fill in these holes.

We now have a fully filled in mask that we can finally use to index into the original image and set our colours. As such:

mask = imclose(mask, strel('disk', 4, 4));
mask = imfill(mask, 'holes');

Here's what the mask looks like now:

Cool! Now the last thing you need to do is colour in those pixels with whatever colour you wish. To do this, you'll need to make a RGB version of your image. As such, simply create red, green and blue channels that replicate the grayscale content of your image and set each channel with the appropriate colour using the pixels defined in the mask.

red = im;
red(mask) = 255;
green = im;
green(mask) = 0;
blue = im;
blue(mask) = 0;
out = cat(3, red, green, blue);
imshow(out);

Remember that for grayscale images, the RGB equivalent has all of the red, green and blue values the same. Once we set the colour for the pupil, stack all of these together as a 3D matrix using cat and we finally show the image. I've also set the colour of the pupil to red. You can change the RGB value to whatever you desire by changing the constant assignment (255, 0, 0) to be your desired colour.

This is what we get:


For your copying and pasting pleasure, this is the full code from start to finish:

im = imread('http://i.stack.imgur.com/d3hy5.jpg');
im = rgb2gray(im);
s = regionprops(im < 35, 'Area', 'PixelList');
areas = [s.Area].';
ind = find(areas == 480);
pix = s(ind).PixelList;
mask = logical(full(sparse(pix(:,2), pix(:,1), 1, size(im,1), size(im,2))));
mask = imclose(mask, strel('disk', 4, 4));
mask = imfill(mask, 'holes');
red = im;
red(mask) = 255;
green = im;
green(mask) = 0;
blue = im;
blue(mask) = 0;
out = cat(3, red, green, blue);
imshow(out);

这篇关于改变眼睛图像中特定区域的颜色[Matlab]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆