I have an image like the following: This is an image with pixel width of just 1 pixel. At places where the curve can go continuously either vertically or horizontally, I need the curves to be joined at those certain places, so that they seem as one long curve (I am writing the points traced by the curve to a CSV). Basically I want to divide the curves vertically and horizontally. So overlapping is not an issue even if it happens. I just want long curves in the end. I tried a method that uses two for loops to do so, which kind of works, but takes a long time for processing because of the number of curves in this image. sortedCoordinates = sorted(cornerPoints, key=lambda x: x[0][0]) jointCount = 0 duplicateListPath1, duplicateListPath2 = [], [] mainDetails = [] for item1 in sortedCoordinates: for item2 in sortedCoordinates: if item1 == item2: continue point1, point2 = item1[1], item2[0] dist = euclideanDistance(point1, point2) if dist <= 3: item1, item2 = sorted(item1, key=lambda x:x[0]), sorted(item2, key=lambda x:x[0]) if item1 == item2: continue jointCount += 1 path1 = traceCurveJoin(copyTopHatCopy, item1[0][::-1], item1[1][::-1]) path2 = traceCurveJoin(copyTopHatCopy, item2[0][::-1], item2[1][::-1]) item1AngleSum, item2AngleSum = 0, 0 for i in range(len(path1) - 1): item1AngleSum += math.degrees(math.atan2(path1[i + 1][1] - path1[1], path1[i + 1][0] - path1[0])) item1Angle = item1AngleSum / len(path1) for i in range(len(path2) - 1): item2AngleSum += math.degrees(math.atan2(path2[i + 1][1] - path2[1], path2[i + 1][0] - path2[0])) item2Angle = item2AngleSum / len(path2) if item1Angle < 0: item1Angle += 180 if item2Angle < 0: item2Angle += 180 if abs(item1Angle - item2Angle) < 90: if path1 in duplicateListPath1 or path2 in duplicateListPath2 or path1 in duplicateListPath1 or path2 in duplicateListPath2: continue if path1 in duplicateListPath2 or path2 in duplicateListPath1 or path1 in duplicateListPath2 or path2 in duplicateListPath1: continue duplicateListPath1.append(path1) duplicateListPath2.append(path2) mainDetails.append((path1, path2)) imageHeight, imageWidth = copyTopHatCopy.shape[:2] imageAnother = np.zeros((imageHeight, imageWidth), np.uint8) oneCount = 0 cutList = [] for i, (ePath1, ePath2) in enumerate(mainDetails): if oneCount == 1: try: csvList.pop(len(csvList) - 1) except: pass oneCount = 0 # with lockOCC: # overallContourCount.value += 1 # finalContourCount = overallContourCount.value path1Start, path1End = ePath1[0], ePath1[-1] path2Start, path2End = ePath2[0], ePath2[-1] distances = { (path1Start, path2Start): euclideanDistance(path1Start, path2Start), (path1Start, path2End): euclideanDistance(path1Start, path2End), (path1End, path2Start): euclideanDistance(path1End, path2Start), (path1End, path2End): euclideanDistance(path1End, path2End) } closestPair = min(distances, key=distances.get) path1Reversed, path2Reversed = ePath1[::-1], ePath2[::-1] if closestPair[0] == path1Start: ePath1 = ePath1[::-1] if closestPair[1] == path2End: ePath2 = ePath2[::-1] intermeadiatePoints = interpolatePoints(closestPair[0], closestPair[1]) joinedPath = np.vstack([ePath1, intermeadiatePoints, ePath2]) Is there any way to do it faster than what I have done? Continue reading...