1

I have a problem and I need your help.

I have a series of thermographic images, of which I need to detect the hot spot (shown in the bar to the right of the image) in the area where the analysis is being done. In the case of these example images, the hot spot is in the focus of the crosshair, however, the goal is to imagine that I don't know where this point is and that the algorithm itself finds it, based on the bar on the right. I leave below some of these images as an example:

IR_1544.jpg

IR_1546.jpg

IR_1548.jpg

IR_1566.jpg

IR_1574.jpg

In this example, the sidebar indicates a temperature range between 33.2 and 97.7 ° C. I would like to identify in the image where the 97.7 ° C point is. Initially I created a code in which I read the BGR value at the highest point of the bar and look for this combination in the rest of the image, this didn't return anything. Not convinced, I created a code that identifies the RGB code in the entire bar and looks in the image, which also did not return anything, the code follows below:

# Find one of temperature bar colors in the image
import cv2
image_path = r"C:\Users\bruno\PycharmProjects\TCC\Imagens\IR_1544.jpg"

img = cv2.imread(image_path)
crop1 = img[69:171, 309:310]

for i in range(70, 172):
    crop = img[i-1:i, 309:310]
    num1, num2, num3 = cv2.split(crop)
    for i in range(0, crop.shape[0]):
        for j in range(0, crop.shape[1]):
            if img[i][j][0] == num1:
                if img[i][j][1] == num2:
                    if img[i][j][2] == num3:
                        print("I found")

cv2.imshow("img1", img)
cv2.imshow("img2", crop1)
cv2.waitKey(0)
cv2.destroyAllWindows()

I would like to know if there is another way that I can identify these colors in the image. I thank everyone who can help !!

  • Is the colour scale always the same? Or could there be different colours for the same temperature? – Mark Setchell May 04 '20 at 20:38
  • There can be different colors for the same temperature, if the thermography is done on a hotter or colder equipment, the color range remains the same, but the maximum and minimum values are different. I will attach other images in the post for you to see better. – Bruno Marques May 04 '20 at 22:30
  • I'm editing my answer. Wait a little bit!!! – Stévillis May 05 '20 at 01:39

1 Answers1

0

I had to follow a lot of tutorials to achieve my goal:
Estimate Brightness of an image Opencv
Convert HSV to grayscale in OpenCV
Finding the Brightest Spot in an Image using Python and OpenCV
OpenCV-Python Tutorials
OpenCV-Python Tutorials
Recognizing digits with OpenCV and Python
Recognise text and digit from the image with Python, OpenCV and Tesseract OCR
Recognize specific numbers from table image with Pytesseract OCR
Convert a number range to another range, maintaining ratio

import cv2
import numpy as np
import pytesseract # used to read the digits on images
from PIL import Image # transformation of image read with OpenCV to use it with pytesseract 


src_path = 'C:/Users/user/Documents/StackOverflow/WarmColorDetection/'
pytesseract.pytesseract.tesseract_cmd = 'C:/Users/user/AppData/Local/Tesseract-OCR/tesseract.exe'


def find_temperature_range(img, y1=0, y2=0, x1=0, x2=0):
    '''
    Find the number that indicates the temperature range for that image.
    :param img: The image where the temperature range is located.
    :param y1: Start of the temperature scale label height.
    :param y2: End of the temperature scale label height.
    :param x1: Start of of the temperature scale label width.
    :param x2: End of of the temperature scale label width.
    :return: A temperature range value read.
    '''
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    roi = gray[y1:y2, x1:x2]  # ROI - Region of Interest

    thresh = cv2.threshold(roi, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    kernel = np.ones((1, 1), np.uint8)
    dilation = cv2.dilate(thresh, kernel, iterations=1)

    # Recognize text with tesseract for python
    binimagem = Image.fromarray(dilation)
    temperature_range = pytesseract.image_to_string(binimagem,
                                                    config='--psm 10 -c tessedit_char_whitelist=01234567890.')
    return float(temperature_range)


def find_warm_pixel(img, radius=3):
    '''
    Find warm pixel in the given image
    :param img: Image where the warm pixel will be searched
    :param radius: kernel
    :return: A tuple with the values of (minVal, maxVal, minLoc, maxLoc)
    '''
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Apply a Gaussian Blur to the image then find the brightest region
    gray = cv2.GaussianBlur(gray, (radius, radius), 0)
    return cv2.minMaxLoc(gray)


if __name__ == '__main__':
    # Loop over all images and show the warm point of all of them
    for i in range(1, 6):
        img = cv2.imread(f'img/img{i}.jpg', 1)
        y, x, _ = img.shape
        img_copy = img.copy()

        max_temp_range = find_temperature_range(img_copy, 45, 60, 280, 315)
        min_temp_range = find_temperature_range(img_copy, 178, 194, 280, 315)

        if i == 1:
            max_temp_range = 97.7  # Could not read the correct number only for this case, as it's showing 77

        (minVal, maxVal, minLoc, maxLoc) = find_warm_pixel(img_copy)

        # Converting a pixel value based on minimum and maximum value range read from the image
        # new_value = ( (old_value - old_min) / (old_max - old_min) ) * (new_max - new_min) + new_min
        old_value = maxVal
        old_min = 0
        old_max = 255
        temperature = ((old_value - old_min) / (old_max - old_min)) * (max_temp_range - min_temp_range) + min_temp_range

        circle_radius = 3
        cv2.circle(img, maxLoc, circle_radius, (255, 0, 0), 2)  # draw a circle around the britest pixel
        cv2.putText(img, f'Coordinate: {maxLoc}', (122, 210), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1,
                    cv2.LINE_AA)
        cv2.putText(img, f'Value: {temperature:.2f}', (122, 225), cv2.FONT_HERSHEY_SIMPLEX, 0.35,
                    (255, 255, 255), 1,
                    cv2.LINE_AA)

        # Display the result
        cv2.namedWindow(f'Image {i}', cv2.WINDOW_GUI_NORMAL)
        cv2.resizeWindow(f'Image {i}', x, y)
        cv2.imshow(f'Image {i}', img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

enter image description here

Stévillis
  • 491
  • 1
  • 6
  • 16
  • Thank you very much for your solution, it is very, very good. I'm intrigued by the fact that it doesn't correspond to the camera's target (which indicates 100 ° C), but maybe it has to do with the temperature range that doesn't show exactly what happens in the image, but in this case, it's FLIR's fault. I will try to find out if there is any way to set the temperature through that maximum point defined by the minMaxLoc function, but you helped me a lot. Thank you!! – Bruno Marques May 05 '20 at 18:47
  • You can increase the radius in the find_warm_pixel function to consider a larger range of analysis. – Stévillis May 05 '20 at 20:48
  • I would also like to detect the temperature in any pixel of the image. I tried to crop the image and apply the find_warm_pixel function, however the value returned in this case (maxVal) is different from when it is performed on the entire image (even in the pixel that was found the hottest point previously), showing a terrible solution. How can I find a maxVal to compare in the temperature equation without using the minMaxLoc function, since it cannot be applied to a pixel? – Bruno Marques May 22 '20 at 20:21
  • 1
    I used the HSV color system and I got it, because the V provides the brightness, it would also work with YUV, where the Y provides the brightness. – Bruno Marques May 23 '20 at 18:42