How to find the center point of this rectangle

2024/10/5 14:50:02

I am trying to find the center point of the green rectangle which is behind the fish, but my approach is not working. Here is my code:

#Finding contours (almost always finds those 2 retangles + some noise):
_, conts, hierarchy = cv2.findContours(img_green, cv2.RETR_TREE , cv2.CHAIN_APPROX_SIMPLE)
for cnt in conts:area = cv2.contourArea(cnt)#filter noiseif area > 25:M = cv2.moments(cnt)x1, y1, w, h = cv2.boundingRect(cnt)x2 = x1 + w                           # (x1, y1) = top-left vertexy2 = y1 + h                           # (x2, y2) = bottom-right vertexcy = int(M['m01']/M['m00'])           # (cx, cy) = rect centercx = int(M['m10']/M['m00'])rect = cv2.rectangle(green_bar_win, (x1, y1), (x2, y2), (255,0,0), 2)center = cv2.circle(green_bar_win, (cx, cy), 2, (0,0,255), 4)

As you can see, it finds the rectangle's contour but divided where the fish is, making 2 different shapes. It also finds the center of this 2 shapes (the blue points), however I don't know how to find the middle of the big one. I thought about averaging all the found rectangle centers but I don't know how to write this out. I am finding the rectangles by hsv color. Help?

EDIT: I have 'y1' from the top rectangle, but don't know how to get y2 from the bottom one while inside the for loop. I tried this:

_, conts, hierarchy = cv2.findContours(img_green, cv2.RETR_TREE , cv2.CHAIN_APPROX_SIMPLE)
for cnt in conts:area = cv2.contourArea(cnt)#filter noiseif area > 25:x1, y1, w, h = cv2.boundingRect(cnt)x2 = x1 + w                           # (x1, y1) = top-left vertextry:rect_center = np.average([y1, y2])except:print("Failed to average")y2 = y1 + h                           # (x2, y2) = bottom-right vertexrect = cv2.rectangle(green_bar_win, (x1, y1), (x2, y2), (255,0,0), 2)

But it still fails, because y2 is used before assigment. So, how could I get y2 from the second loop itineration before y1 is overwritten by the 'for' loop?

Answer

It's time to break this to a full answer.

After you identify each rectangle, compare its corners to each existing shape. If it has the same color and a pair of corners in common (shared edge), then update the old rectangle: replace those two corners with the other corners of the new rectangle.

Add a couple of things to your code:

  1. keep a list of the shapes found so far
  2. as you find each shape, compare to the ones found already.

    rect_list = []

    for cnt in conts:area = cv2.contourArea(cnt)

    #filter noise
    if area > 25:M = cv2.moments(cnt)# ... several lines deletedrect = cv2.rectangle(green_bar_win, (x1, y1), (x2, y2), (255,0,0), 2)center = cv2.circle(green_bar_win, (cx, cy), 2, (0,0,255), 4)# Look for adjacent shapes herefor old_rect in rect_list:# fetch the corners of old_rect# if old_rect has a pair of corners in common with#     the current rect, then merge the two.#     Do this by expanding the corners of old_rect.else:rect_list.append(rect)
    
https://en.xdnf.cn/q/119668.html

Related Q&A

Simple Battleships game implementation in Python

Okay Im not sure how to develop another board with hidden spaces for the computers ships per-se, and have it test for hits. Again Im not even sure how Im going to test for hits on the board I have now.…

How to remove WindowsPath and parantheses from a string [duplicate]

This question already has an answer here:Reference - What does this regex mean?(1 answer)Closed 4 years ago.I need to remove WindowsPath( and some of the closing parentheses ) from a directory string.…

How to escape escape-characters

I have a string variable which is not printing properly, I guess because it contains escape characters. How to escape these escape-characters?>>> print "[p{Aa}\\P{InBasic_Latin}\r\t\n]&q…

Python Multiprocessing a large dataframe on Linux

As shown in the title, I have a big data frame (df) that needs to be processed row-wise, as df is big (6 GB), I want to utilize the multiprocessing package of python to speed it up, below is a toy exam…

How to pass more arguments through tkinter bind

How do I pass more arguments through tkinters bind method? for the example:tk = Tk() def moveShip(event,key):if event.keysym == Down and player1.selectedCoord[1] != 9:if key == place:player1.selectedC…

Python Class method definition : unexpected indent [duplicate]

This question already has answers here:Im getting an IndentationError (or a TabError). How do I fix it?(6 answers)Closed 6 months ago.I am getting started with Django and Python so naturally Im doing …

pandas python - round() not behaving correctly

Im rounding values in a dataframe to 1 decimal place. Here is the dfVren 2015 Hsten 2014 Vren 2014 Question 1) Maten r vllagad oc…

Converting dictionary into string

d={a:Apple,b:ball,c:cat}The above dictionary I have and I want my Output like the below-mentioned resultres="a=Apple,b=ball,c=cat"Is it possible in a pythonic way then please answer it I have…

Django Getting QuerySet.values() based on condition

Lets say I have a model Class Parent and a Class Child. And child has a field called status and a ForeignKey relationship to Parent.Lets say I retrieve one parent by calling filter (so as to have a Que…

Condition checking in python with user input [duplicate]

This question already has answers here:If...else statement issue with raw_input on Python(2 answers)Closed 8 years ago.I tried taking an input from keyboard. the checking that input with an if else sta…