To achieve this we will need to detect sections of the contour where the "x" coordinate is growing or decreasing. But if we work with the contour as it is now we will have many such positions. So first I suggest working with points distanced five from each other.
Then you have to take one of the prominent points of the tail to use as reference and iterate over the neighbours until the "x" coordinate change its direction. This is the desired point.
I did some of the work for you.
import cv2
import numpy as np
import matplotlib.pyplot as plt
import math
img = cv2.imread("Inkedfish.jpg")
# some preprocessing
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = cv2.dilate(img2, (3,3))
img2 = cv2.blur(img2, (3, 3))
_, thresh = cv2.threshold(img2, 10, 255, 0)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0]
fish_points = []
i = 0
j = 1
while i + j < len(contours):
j = 1
while i + j < len(contours):
fixed_x = contours[i][0][0]
fixed_y = contours[i][0][1]
current_x = contours[i + j][0][0]
current_y = contours[i + j][0][1]
distance = math.sqrt((current_x - fixed_x) ** 2 + (current_y - fixed_y) ** 2)
if distance >= 5:
fish_points.append(contours[i + j][0])
i = i + j
break
j += 1
inflection_points = []
previous_direction = "decreasing"
for i in range(len(fish_points)):
current_x = fish_points[i][0]
previous_x = fish_points[i - 1][0]
current_direction = None
if current_x >= previous_x:
current_direction = "increasing"
else:
current_direction = "decreasing"
if current_direction == "decreasing" and previous_direction == "increasing":
inflection_points.append(fish_points[i])
previous_direction = current_direction
tail_point = None
i = 0
while i < len(fish_points):
current_x = fish_points[i][0]
previous_x = fish_points[i - 1][0]
if current_x > previous_x:
tail_point = fish_points[i]
break
i += 1
def convert(points):
x_values = []
y_values = []
for point in points:
x_values.append(point[0])
y_values.append(point[1])
return x_values, y_values
x_values, y_values = convert(fish_points)
x_values_inflection, y_values_inflection = convert(inflection_points)
#plt.plot(x, y, color="red")
plt.scatter(x_values, y_values, color="red")
plt.scatter(x_values_inflection, y_values_inflection, color="blue")
plt.scatter(tail_point[0], tail_point[1], color="green")
plt.gca().invert_yaxis()
plt.show()