Defining color range for histologic image mask within HSV colorspace (Python, OpenCV, Image-Analysis):

匿名 (未验证) 提交于 2019-12-03 01:34:02

问题:

In an effort to separate histologic slides into several layers based on color, I modified some widely distributed code (1) available through OpenCV's community. Our staining procedure marks different cell types of tissue cross sections with different colors (B cells are red, Macrophages are brown, background nuceli have a bluish color).

I'm interested in selecting only the magenta-colored and brown parts of the image.

Here's my attempt to create a mask for the magenta pigment:

    import cv2     import numpy as np      def mask_builder(filename,hl,hh,sl,sh,vl,vh):         #load image, convert to hsv         bgr = cv2.imread(filename)         hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)         #set lower and upper bounds of range according to arguements         lower_bound = np.array([hl,sl,vl],dtype=np.uint8)         upper_bound = np.array([hh,sh,vh],dtype=np.uint8)         return cv2.inRange(hsv, lower_bound,upper_bound)      mask = mask_builder('sample 20 138 1.jpg', 170,180, 0,200, 0,230)     cv2.imwrite('mask.jpg', mask) 

So far a trial and error approach has produced poor results:

The can anyone suggest a smarter method to threshhold within the HSV colorspace? I've done my best to search for answers in previous posts, but it seems that these color ranges are particularly difficult to define due to the nature of the image.

References:

  1. Separation with Colorspaces: http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html
  2. python opencv color tracking
  3. BGR separation: http://www.pyimagesearch.com/2014/08/04/opencv-python-color-detection/

UPDATE: I've found a working solution to my problem. I increased the lower bound of 'S' and 'V' by regular intervals using a simple FOR control structure, outputing the results for each test image and choosing the best. I found my lower bounds for S and V should be set at 100 and 125. This systematic method of trial and error produced better results:

回答1:

I am happy you found your answer.

I will suggest an alternate method that might work. Unfortunately I am not proficient with python so you'll need to find out how to code that in python (its basic).

If I had the firs image you have after the HSV threshold, I would use morphological operations to get the information I want.

I would probably give it a go to "closing", but if it doesnt work I would first dilate, then fill and then erode the same amount firstly dilated.

Probably after this first step you'll need to delete the small "noise" blobs you have around and you'll get the image.

This is how it would be in Matlab (showing this mainly so you can see the results):

I=imread('http://i.stack.imgur.com/RlH4V.jpg');  I=I>230;                        % Create Black and white image (this is because in stackoverflow its a jpg) ker=strel('square',3);          % Create a 3x3 square kernel  I1=imdilate(I,ker);             % Dilate I2=imfill(I1,'holes');          % Close I3=imerode(I2,ker);             % Erode  Ilabel=bwlabel(I3,8);            % Get a label per independent blob  % Get maximum area blob (you can do this with a for in python easily) areas = regionprops(Ilabel,'Centroid','Area','PixelIdxList'); [~,index] = max([areas.Area]);   % Get the maximum area  Imask=Ilabel==index;             % Get the image with only the max area.    % Plot: This is just matlab code, no relevance  figure; subplot(131) title('Dialted') imshow(I1); subplot(132) title('Closed') imshow(I2); subplot(133) title('Eroded') imshow(I3);   figure; imshow(imread('http://i.stack.imgur.com/ZqrF9.jpg')) hold on h=imshow(bwperim(Imask)); set(h,'alphadata',Imask/2) 

Note that I started from the "bad" HSV segmentation. If you try a better one the results may improve. Also, play with the kernel size for the erosion and dilation.



回答2:

Through trial-and-error (incrementing down and up the "S" and "V" scales), I found that my desired colors require a relaxed range for "S" and "V" values. I'll refrain from sharing the particular values I use because I don't think anyone would find such information useful.

Note that the original code shared works fine once more representitive ranges are used.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!