Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR] Implement building bipartite graph, calculate cost values of each edge, assign and make humans #42

Merged
merged 8 commits into from
May 1, 2020

Conversation

tucan9389
Copy link
Owner

@tucan9389 tucan9389 commented Apr 30, 2020

Related Issues

PR Points

  • Fix pair information on OpenPosePoseEstimator.Output.BodyPart.lines correctly
  • Implement the logic building bipartite graph
  • Calculate the cost of edges with line integral
  • Implement to assign by using the cost
  • Implement to make humans with the left edges

1. NMS

#38

2. Bipartite Graph

Bipartite graph - Wikipedia

Description of Bipartite Graph

3. Line Integral

Line integral - Wikipedia

  1. Sampling the target values between starting keypoint and ending keypoint
  2. Calculate with dot product for each sample and sum
Equation Description

ref

ref: wiki
Example of nth pair's cost

4. Assignment

Sort by cost on a pair and perform assignment process.

In the following pair case, only 2 connections remain from 6 connection candidates.

  • 0th keypoint of 0th part and 0th keypoint of 1st part
  • 2nd keypoint of 0th part and 1st keypoint of 1st part

5. Merging

Preparing...

Reference

@tucan9389 tucan9389 requested a review from syjdev April 30, 2020 07:25
@tucan9389 tucan9389 self-assigned this Apr 30, 2020
@tucan9389 tucan9389 linked an issue Apr 30, 2020 that may be closed by this pull request
8 tasks
}
return Human(keypoints: keypoints, lines: [])
}
}

func parseAllPartOnMultiHuman(from output: TFLiteFlatArray<Float32>, with threshold: Float?) -> [Human] {
Copy link
Collaborator

@syjdev syjdev Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to divide 'parseAllPartOnMultiHuman' to tasks.

example)

func parseAllPartOnMultiHuman() {
   ...
   makePair()
   makeEdgesForEachPair()
   merge()
   makeHumans()
}

When you divide 'parseAllPartOnMultiHuman',
you have to make a tasks that have same abstract level.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggestion is really important, but I'll refactoring on next PR soon.


// return []
// 5. Merging
var tmpHumans: [[(col: Int, row: Int, val: Float32)?]] = []
Copy link
Collaborator

@syjdev syjdev Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you possible, Don't use 'tmp'.
It's looks incomplete code.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to change. thx :)

}

guard let startingPartVertices = verticesForEachPart[startingPartIndex],
let endingPartVertices = verticesForEachPart[endingPartIndex] else { fatalError("cannot get verties for assignment") }
Copy link
Collaborator

@syjdev syjdev Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can 'output.keypoints' return nil?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@syjdev
No. startingPartVertices and endingPartVertices type's element can be nil. Because startingPartVertices and endingPartVertices are initialized with nil in fixed size.
But it's weird... I'll change startingPartVertices and endingPartVertices to non-nil element array and try to remove the guard statement.
👍

@@ -61,7 +61,9 @@ class OpenPosePoseEstimator: PoseEstimator {
}

var pairNames: [String]? {
return nil
return Output.BodyPart.lines.map {
return "\($0.from.shortName())-\($0.to.shortName())"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"($0.from.shortName())-($0.to.shortName())" is always String.
This expression never become Optional.

So, I recommend to use [String] for pairNames's type instead [String?].

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@syjdev
pairNames property is defined on PoseEstimator protocol as get-only.
There are 4 classes confirmed PoseEstimator protocol:

  • PoseNetPoseEstimator
  • PEFMCPMPoseEstimator
  • PEFMHourglassPoseEstimator
  • OpenPosePoseEstimator

But OpenPosePoseEstimator return non-nil array on pairNames and others return nil, because PoseNetPoseEstimator, PEFMCPMPoseEstimator, and PEFMHourglassPoseEstimator don't support multi pose estimation.

// sampling
let numberOfSamples = 10
let dx = Float(xDiff) / Float(numberOfSamples)
let dy = Float(yDiff) / Float(numberOfSamples)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are types of xDiff, yDiff Float?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@syjdev
Oh, that's right. There is no need to cast.

}
}

edges.sort { $0.cost > $1.cost }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you sort edges twice. is this alright?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was my mistake. Thx 👍

@tucan9389 tucan9389 changed the title [PR] Implement building bipartite graph, calculate cost values of each edge, assign and make humans [PR✨] Implement building bipartite graph, calculate cost values of each edge, assign and make humans May 1, 2020
@tucan9389 tucan9389 changed the title [PR✨] Implement building bipartite graph, calculate cost values of each edge, assign and make humans [✨PR✨] Implement building bipartite graph, calculate cost values of each edge, assign and make humans May 1, 2020
@tucan9389 tucan9389 changed the title [✨PR✨] Implement building bipartite graph, calculate cost values of each edge, assign and make humans [PR] Implement building bipartite graph, calculate cost values of each edge, assign and make humans May 1, 2020
@tucan9389 tucan9389 merged commit 98d29ba into feature/multi-pose May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support OpenPose tflite model (multi-pose)
2 participants