0

I would like to filter the image below into green and red. The aim of filtering the image is to be able to count the red and green cells in the image. I am using OpenCV to filter the image but the outcome isn't as expected please see images in Red and green filter. The filtered image seems to include more cells in either color, which will lead to an incorrect count. Is there anything I could do in the code to improve this, please? Many Thanks in advance.

import cv2

image = cv2.imread('2020-03-Sequence-p4-Day-0_Position070.png')

b = image.copy()
# set green and red channels to 0
b[:, :, 1] = 0
b[:, :, 2] = 0


g = image.copy()
# set blue and red channels to 0
g[:, :, 0] = 0
g[:, :, 2] = 0

r = image.copy()
# set blue and green channels to 0
r[:, :, 0] = 0
r[:, :, 1] = 0


# RGB - Blue
cv2.imshow('B-RGB', b)

# RGB - Green
cv2.imshow('G-RGB', g)

# RGB - Red
cv2.imshow('R-RGB', r)

cv2.waitKey(0)

Originalenter image description here image converted_images enter image description here

Browed1983
  • 179
  • 2
  • 7
  • 16
  • 1
    looks green and red to me... whats the problem? – BenedictWilkins Aug 01 '20 at 10:00
  • @BenedictWilkinsAI If you take a look at the original image, you can see that the filtering is showing more red cells in green. I was hoping when I apply the filter the image will only show the red cells that are only are red in the original and the same for the green cells. I have tried to use the split method in OpenCV but this is taking a lot of resources when applying to all the images. The system keeps given an error running out of memory. I am not sure which method is better, to be honest. I would be grateful for an advice. – Browed1983 Aug 01 '20 at 11:00
  • I'm not sure I understand.... What is a cell ? – BenedictWilkins Aug 01 '20 at 11:03
  • 3
    Have a look here... https://stackoverflow.com/a/50215020/2836621 and, for reds, here... https://stackoverflow.com/a/58082661/2836621 – Mark Setchell Aug 01 '20 at 11:09
  • 3
    And here... https://stackoverflow.com/a/52183666/2836621 – Mark Setchell Aug 01 '20 at 11:12
  • @BenedictWilkinsAI It is cells taken using a microscope. – Browed1983 Aug 01 '20 at 11:15
  • 1
    You are setting the other channels to 0 which means that even if it was not dominating erarlier, it will now. Instead I would recommend to set only the pixels where blue and green is less than red to 0 for the red one and subsequently for the green one. – Vardan Agarwal Aug 01 '20 at 14:52
  • 1
    In addition to this you also set a threshold like 128 or something to make sure only the red ones are shown which you can then count. – Vardan Agarwal Aug 01 '20 at 15:13

1 Answers1

1

Do you mean something like this:

import cv2
import numpy as np

## Read
img = cv2.imread("img.jpg")

## convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

mask_green = cv2.inRange(hsv, (36, 25, 25), (70, 255,255))
mask_red1 = cv2.inRange(hsv, (0, 70, 50), (10, 255, 255))
mask_red2 = cv2.inRange(hsv, (170, 70, 50), (180, 255, 255))
mask_orange = cv2.inRange(hsv, (10, 100, 20), (25, 255, 255))
mask_yellow = cv2.inRange(hsv, (21, 39, 64), (40, 255, 255))

## slice the red and orange
imask_red1 = mask_red1>0
imask_red2 = mask_red2>0
imask_orange = mask_orange>0
imask_yellow = mask_yellow>0
red = np.zeros_like(img, np.uint8)
red[imask_red1] = img[imask_red1]
red[imask_red2] = img[imask_red2]
red[imask_orange] = img[imask_orange]
red[imask_yellow] = img[imask_yellow]

## slice the green
imask_green = mask_green>0
green = np.zeros_like(img, np.uint8)
green[imask_green] = img[imask_green]

## save 
cv2.imwrite("green.jpg", green)
cv2.imwrite("red.jpg", red)

enter image description here enter image description here

Some of the green is getting carried over into the red version, I guess you could adjust the hsv range to fix that