

# https://www.globalsino.com/ICs/
# Detect a scale bar / scalebar calibration by clicking the start and end of the scale bar on desktop

import cv2
import numpy as np
from matplotlib import pyplot as plt
# import matplotlib.pyplot as plt
import PIL.ImageGrab
from PIL import Image
from pynput.mouse import Listener
from threading import Timer
import skimage.io

savedScreenShot = r"C:\GlobalSino2\ICs\images2\4033ScreenShotA.png"
edgeImageOfScreenshot = r"C:\GlobalSino2\ICs\images2\4033ScreenShotEdge.png"
StartOfScalebar = r"C:\GlobalSino2\ICs\images2\StartOfScalebar.png"
CenterOfStartOfScalebar = r"C:\GlobalSino2\ICs\images2\CenterOfStartOfScalebar.png"
EndOfScalebar = r"C:\GlobalSino2\ICs\images2\EndOfScalebar.png"

# Take a full screenshot
My_screen_shot = PIL.ImageGrab.grab()
My_screen_shot.save(savedScreenShot)

# Read the screenshot file and convert it to a grey image
img = cv2.imread(savedScreenShot)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)[:, :, 2]
kern_size = 3 # 11 =========================
gray_blurred = cv2.medianBlur(gray, kern_size)

# Get an edge image ======= 20- 40 / 10 - 70 ===================
threshold_lower = 5
threshold_upper = 20
edged = cv2.Canny(gray_blurred, threshold_lower, threshold_upper)

# cv2.imshow('edged',edged)
cv2.imwrite(edgeImageOfScreenshot, edged)  # =============
# cv2.imshow('My image', edged) 

# Draw a line on the grey image
img = cv2.imread(edgeImageOfScreenshot)

# Get the start point and end point for the scale bar.
PositionList = []
def myClick(x,y, button, pressed):
    global PositionList
    if pressed:
        x = int(x)
        y = int(y)
        PositionList.append((x,y))

        # Limit it to 2 clickes
        if len(PositionList) == 2:
            print(PositionList)
            return PositionList

with Listener(on_click = myClick) as Listener:
    # Timer: 8 seconds ====================
    Timer(8, Listener.stop).start()
    Listener.join()

# Start point
start0 = PositionList[0]
openEdgeImage = Image.open(edgeImageOfScreenshot)
# Crop for start point of scalebar
print("Clicked pixel at start0 is: ", start0)
halfWidthOfStart = 10 # ================================
img_start = openEdgeImage.crop((start0[0]-halfWidthOfStart/2, start0[1]-halfWidthOfStart, start0[0]+halfWidthOfStart/2, start0[1]+halfWidthOfStart))
img_start.save(StartOfScalebar, quality=95)
img_start.show()
# Locate the nearest pixel to the clicked spot
img_grey_start = cv2.imread(StartOfScalebar,cv2.IMREAD_GRAYSCALE)
print(img_grey_start.shape)
# ref = (150,150)
def nearest_white_start(img_grey_start, target):
    # get a numpy array of coordinates of all the white pixels
    nonzero = cv2.findNonZero(img_grey_start)
    # print(nonzero)
    # calculate distance from the clicked target point (Pythagoras theorem)
    distances = np.sqrt((nonzero[:,:,0] - target[0]) ** 2 + (nonzero[:,:,1] - target[1]) ** 2)
    # find the position of the lowest distance
    nearest_index = np.argmin(distances)
    # Return the coordinates of the corresponding nonzero pixel.
    return nonzero[nearest_index]
nearest_white_pixel_start = nearest_white_start(img_grey_start, start0)
print("nearest_white_pixel_start is: ", nearest_white_pixel_start)
print("start0[0]", start0[0])
print("start0[1]", start0[1])
x_start = start0[0] + nearest_white_pixel_start[0][0] - halfWidthOfStart
y_start = start0[1] 
# y_start = start0[1] + nearest_white_pixel_start[0][1] - halfWidthOfStart # =====================
start = (x_start, y_start)


# End point
end0 = PositionList[1]
# openEdgeImage = Image.open(edgeImageOfScreenshot)
# Crop for end point of scalebar
print("Clicked pixel at end0 is: ", end0)
halfWidthOfEnd = 5
img_end = openEdgeImage.crop((end0[0]-halfWidthOfEnd/2, end0[1]-halfWidthOfEnd, end0[0]+halfWidthOfEnd/2, end0[1]+halfWidthOfEnd))
img_end.save(EndOfScalebar, quality=95) 
img_end.show()
# Locate the nearest pixel to the clicked spot
img_grey_end = cv2.imread(EndOfScalebar, cv2.IMREAD_GRAYSCALE)
print(img_grey_end.shape)
def nearest_white_end(img_grey_end, target):
    # get a numpy array of coordinates of all the white pixels
    nonzero = cv2.findNonZero(img_grey_end)
    # print(nonzero)
    # calculate distance from the clicked target point (Pythagoras theorem)
    distances = np.sqrt((nonzero[:,:,0] - target[0]) ** 2 + (nonzero[:,:,1] - target[1]) ** 2)
    # find the position of the lowest distance
    nearest_index = np.argmin(distances)
    # Return the coordinates of the corresponding nonzero pixel.
    return nonzero[nearest_index]
nearest_white_pixel_end = nearest_white_end(img_grey_end, end0)
print("nearest_white_pixel_end is: ", nearest_white_pixel_end)
print("end0[0]", end0[0])
print("end0[1]", end0[1])
x_end = end0[0] + nearest_white_pixel_end[0][0] - halfWidthOfEnd
y_end = end0[1] # + nearest_white_pixel_end[0][1] - halfWidthOfEnd
end = (x_end, y_end)

print(end)

# End coordinate, here (250, 250)
# end = PositionList[1]
# The line color in white
color = (0, 0, 255)
# Line thickness of 1 px
thickness = 2
# Draw a white line with a thickness of 1 px
img = cv2.line(img, start, end, color, thickness)
# Display the image 
cv2.imshow('My image', img)

cv2.waitKey(0)
cv2.destroyAllWindows()













