简体   繁体   中英

How to find the average RGB value of a circle in an image with python?

I'm trying to help a colleague that uses a very old colorimetric technique to measure cellular death. To simplify the problem here is a schematic image:

在此处输入图像描述

This is known as a 96-well plate. I need to find all the wells and return the RGB value for each one. Pink means all cells are alive and blue means no cell is alive. They have a formula for this calculation. Now I have been working with this image and so far I can detect all wells with this code:

import cv2 
import numpy as np 

# Read image. 
img = cv2.imread('images/placaTeoricaCompleta_result.jpg') 

# Convert to grayscale. 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 

# Blur using 3 * 3 kernel. 
gray_blurred = cv2.blur(gray, (3, 3))


# Apply Hough transform on the blurred image. 
detected_circles = cv2.HoughCircles(gray_blurred, 
                cv2.HOUGH_GRADIENT, 1.2, 20, param1 = 50, 
            param2 = 30, minRadius = 30, maxRadius = 50) 

# Draw circles that are detected. 
if detected_circles is not None: 

    # Convert the circle parameters a, b and r to integers. 
    detected_circles = np.uint16(np.around(detected_circles))

    for pt in detected_circles[0, :]: 
        a, b, r = pt[0], pt[1], pt[2] 

        # Draw the circumference of the circle. 
        cv2.circle(img, (a, b), r, (0, 255, 0), 2) 

        # Draw a small circle (of radius 1) to show the center. 
        cv2.circle(img, (a, b), 1, (0, 0, 255), 3) 
    
    cv2.imshow("Detected Circle", img) 
    cv2.waitKey(0) 

But I can't find a way to return the RGB value for each well.

A real image would look something like this:

在此处输入图像描述

How do I return the RGB value for each circle? This would preferably be in order from A to H and from 1 to 12, or otherwise write the RGB value in the circle.

You can generate a mask for each circle, then obtain the mean of the color channels. The following code is just for one circle, but you can just put it in a for loop:

x, y, r = detected_circles[0].astype(np.int32)
roi = image[y - r: y + r, x - r: x + r]

感兴趣的区域

# generate mask
width, height = roi.shape[:2]
mask = np.zeros((width, height, 3), roi.dtype)
cv2.circle(mask, (int(width / 2), int(height / 2)), r, (255, 255, 255), -1)

面具

dst = cv2.bitwise_and(roi, mask)

蒙版图像

# filter black color and fetch color values
data = []
for i in range(3):
    channel = dst[:, :, i]
    indices = np.where(channel != 0)[0]
    color = np.mean(channel[indices])
    data.append(int(color))

# opencv images are in bgr format
blue, green, red = data # (110, 74, 49)

最终图像

The text in the image is in rgb format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM