Question: I have frames of a video taken from a microscope. I need to crop them to a square inscribed to the circle but the issue is that the circle isn't whole (like in the following image). How can I do it?  My idea was to use contour finding to get the center of the circle and then find the distance from each point over the whole array of coordinates to the center, take the maximum distance as the radius and find the corners of the square analytically but there must be a better way to do it (also I don't really have a formula to find the corners).

Answer: Let's start with an illustration of the problem to help with the explanation.   Of course, we have to begin with loading the image. Let's also grab its width and height, since they will be useful later on. img = cv2.imread('TUP74.jpg', cv2.IMREAD_COLOR) height, width = img.shape[:2]   First, let's convert the image to grayscale and then apply threshold to make the circle all white, and the background black. I arbitrarily picked a threshold value of 31, which seems to give reasonable results. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(img_gray, 31, 255, cv2.THRESH_BINARY)  The result of those operations looks like this:   Now, we can determine the "top" and "bottom" of the circle (first_yd and last_yd), by finding the first and last row that contains at least one white pixel. I chose to use cv2.reduce to find the maximum of each row (since the thresholded image only contains 0's and 255's, a non-zero result means there is at least 1 white pixel), followed by cv2.findNonZero to get the row numbers. reduced = cv2.reduce(thresh, 1, cv2.REDUCE_MAX) row_info = cv2.findNonZero(reduced) first_yd, last_yd = row_info[0][0][1], row_info[-1][0][1]  This information allows us to determine the diameter of the circle d, its radius r (r = d/2), as well as the Y coordinate of the center of the circle center_y. diameter = last_yd - first_yd radius = int(diameter / 2) center_y = first_yd + radius   Next, we need to determine the X coordinate of the center of the circle center_x. Let's take advantage of the fact that the circle is cropped on the left-hand side. The white pixels in the first column of the threshold image represent a chord c of the circle (red in the diagram). Again, we begin with finding the "top" and "bottom" of the chord (first_yc and last_yc), but since we're working with a single column, we only need cv2.findNonZero. row_info = cv2.findNonZero(thresh[:,0]) first_yc, last_yc = row_info[0][0][1], row_info[-1][0][1] c = last_yc - first_yc  Now we have a nice right-angled triangle with one side adjacent to the right angle being half of the chord c (red in the diagram), the other adjacent side being the unknown offset o, and the hypotenuse (green in the diagram) being the radius of the circle r. Let's apply Pythagoras' theorem: r2 = (c/2)2 + o2 o2 = r2 - (c/2)2 o = sqrt(r2 - (c/2)2) And in Python: center_x = int(math.sqrt(radius**2 - (c/2)**2))   Now we're ready to determine the parameters of the inscribed square. Let's keep in mind that the center of the circle and center of its inscribed square are co-located. Here is another illustration:  We will again use Pythagoras' theorem. The hypotenuse of the right triangle is again the radius r. Both of the sides adjacent to the right angle are of equal length, which is half the length of the side of inscribed square s. r2 = (s/2)2 + (s/2)2 r2 = 2 × (s/2)2 r2 = 2 × s2/22 r2 = s2/2 s2 = 2 × r2 s = sqrt(2) × r  And in Python: s = int(math.sqrt(2) * radius)  Finally, we can determine the top-left and bottom-right corners of the inscribed square. Both of those points are offset by s/2 from the common center. half_s = int(s/2) tl = (center_x - half_s, center_y - half_s) br = (center_x + half_s, center_y + half_s)   We have determined all the parameters we need. Let's print them out... Circle diameter = 1167 pixels Circle radius = 583 pixels Circle center = (404,1089) Inscribed square side = 824 pixels Inscribed square top-left = (-8,677) Inscribed square bottom-right = (816,1501)  and visualize the center (green), the detected circle (red) and the inscribed square (blue) on a copy of the input image:   Now we can do the cropping, but first we have to make sure we don't go out of bounds of the source image. crop_left = max(tl[0], 0) crop_top = max(tl[1], 0) # Kinda redundant, but why not crop_right = min(br[0], width) crop_bottom = min(br[1], height) # ditto cropped = img[crop_top:crop_bottom, crop_left:crop_right]  And that's it. Here's the cropped image (it's rectangular, since small part of the inscribed square falls outside the source image, and scaled down for embedding -- click to get the full-sized image):   Complete Script import cv2 import numpy as np import math img = cv2.imread('TUP74.jpg', cv2.IMREAD_COLOR) height, width = img.shape[:2] img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(img_gray, 31, 255, cv2.THRESH_BINARY) # Find top/bottom of the circle, to determine radius and center reduced = cv2.reduce(thresh, 1, cv2.REDUCE_MAX) row_info = cv2.findNonZero(reduced) first_yd, last_yd = row_info[0][0][1], row_info[-1][0][1] diameter = last_yd - first_yd radius = int(diameter / 2) center_y = first_yd + radius # Repeat again, just on first column, to find length of a chord of the circle row_info = cv2.findNonZero(thresh[:,0]) first_yc, last_yc = row_info[0][0][1], row_info[-1][0][1] c = last_yc - first_yc # Apply Pythagoras theorem to find the X offset of the center from the chord # Since the chord is in row 0, this is also the X coordinate center_x = int(math.sqrt(radius**2 - (c/2)**2)) # Find length of the side of the inscribed square (Pythagoras again) s = int(math.sqrt(2) * radius) # Now find the top-left and bottom-right corners of the square half_s = int(s/2) tl = (center_x - half_s, center_y - half_s) br = (center_x + half_s, center_y + half_s) # Let's print out what we found print("Circle diameter = %d pixels" % diameter) print("Circle radius = %d pixels" % radius) print("Circle center = (%d,%d)" % (center_x, center_y)) print("Inscribed square side = %d pixels" % s) print("Inscribed square top-left = (%d,%d)" % tl) print("Inscribed square bottom-right = (%d,%d)" % br) # And visualize it... vis = img.copy() cv2.line(vis, (center_x-5,center_y), (center_x+5,center_y), (0,255,0), 3) cv2.line(vis, (center_x,center_y-5), (center_x,center_y+5), (0,255,0), 3) cv2.circle(vis, (center_x,center_y), radius, (0,0,255), 3) cv2.rectangle(vis, tl, br, (255,0,0), 3) # Write some illustration images cv2.imwrite('circ_thresh.png', thresh) cv2.imwrite('circ_vis.png', vis) # Time to do some cropping, but we need to make sure the coordinates are inside the bounds of the image crop_left = max(tl[0], 0) crop_top = max(tl[1], 0) # Kinda redundant, but why not crop_right = min(br[0], width) crop_bottom = min(br[1], height) # ditto cropped = img[crop_top:crop_bottom, crop_left:crop_right] cv2.imwrite('circ_cropped.png', cropped)   NB: The main focus of this was the explanation of the algorithm. I've been kinda blunt on rounding the values, and there may be some off-by-one errors. For the sake of brevity, error checking is minimal. It's left as an excercise to the reader to address those issues as necessary. Furthermore, the assumption is that the left-hand side of the circle is cropped as in the sample image. It should be fairly trivial to extend this to handle other possible scenarios, using the techniques I've demonstrated.