How to distinguish this line

I have the following code that I’ve been struggling to follow a simple white line. The problem comes if it’s outside and the sun/shadow start changing the color that the camera sees.

I am using RGB to HSV to see the group of white. Yet it has issues when the sun is bright and within the image. Or if the background where the line is place, if it’s gray close to white it’s an issue. What can I add to make it robust?! Attached are pictures of the change in scenery.

#!/usr/bin/env python

import rospy
import cv2
import numpy as np
from cv_bridge import CvBridge, CvBridgeError
from geometry_msgs.msg import Twist
from sensor_msgs.msg import Image, CompressedImage
from move_robot import MoveKobuki
from pid_control import PID
import time

class LineFollower(object):

    def __init__(self):
        rospy.logwarn("Init line Follower")
        self.bridge = CvBridge() 
        self.image_sub = rospy.Subscriber('/camera/image_raw/compressed', CompressedImage, self.camera_callback, queue_size = 1)
        self.movekobuki_object = MoveKobuki()
        self.pid_object = PID()

    def camera_callback(self,data):
        try:
            image_np = self.bridge.compressed_imgmsg_to_cv2(data)
        except CvBridgeError as e:
            print(e)
        
        height, width, channels = image_np.shape
        descentre = 50
        rows_to_watch = 15
        crop_img = image_np[(height)/2+descentre:(height)/2+(descentre+rows_to_watch)][1:width]

        # Blur Image (to help with color noise)
        blur = cv2.medianBlur(crop_img,15)
        
        # Convert from RGB to HSV
        hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

        lower_yellow = np.array([52,0,164], dtype=np.uint8) 
        upper_yellow = np.array([138,55,244], dtype=np.uint8) 
        mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

        try:
            cx, cy = m['m10']/m['m00'], m['m01']/m['m00']
        except ZeroDivisionError:
            cx = 240
            cy = 320

        # Bitwise-AND mask and original image
        res = cv2.bitwise_and(crop_img,crop_img, mask= mask)


        # Draw the centroid in the resulting image
        cv2.circle(res, (int(cx), int(cy)), 10,(0,0,255),-1)

you need white balance. see about setting that to automatic instead of fixed. you might also need something that adapts to the brightness/value instead of fixed thresholds.

why do you select “yellow”? the line is supposed to be white, which means low saturation, high value.

and your code refers to m (moments) that were never calculated. please take better care in writing your questions.