bugfixes
This commit is contained in:
parent
cf5888d9e5
commit
ec4fcea9b1
@ -373,7 +373,7 @@ func trainingPredictionToHighlightResults(pred TrainingPrediction) []NsfwFrameRe
|
||||
}
|
||||
|
||||
comboScore := math.Min(positionScore, score)
|
||||
addHighlightResult(best, "combo:"+sexPosition+"+"+prefix+":"+label, comboScore)
|
||||
addHighlightResult(best, "combo:position:"+sexPosition+"+"+prefix+":"+label, comboScore)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1504,8 +1504,21 @@ func buildCombinedHighlightHitFromPrediction(pred TrainingPrediction, t float64)
|
||||
best := map[string]highlightSignal{}
|
||||
|
||||
sexPosition := strings.ToLower(strings.TrimSpace(pred.SexPosition))
|
||||
if sexPosition != "" && sexPosition != "unknown" {
|
||||
addHighlightSignal(best, "position:"+sexPosition, pred.SexPositionScore)
|
||||
|
||||
if sexPosition != "" && sexPosition != "unknown" && isKnownPositionLabel(sexPosition) {
|
||||
positionScore := pred.SexPositionScore
|
||||
if positionScore <= 0 {
|
||||
positionScore = 0.35
|
||||
}
|
||||
|
||||
// Position soll als Kontext in Kombis bleiben.
|
||||
// Sie erzeugt weiterhin kein Segment alleine, weil unten mindestens
|
||||
// ein Nicht-Positionssignal verlangt wird.
|
||||
best["position:"+sexPosition] = highlightSignal{
|
||||
Label: "position:" + sexPosition,
|
||||
Score: math.Max(positionScore, 0.20),
|
||||
Group: "position",
|
||||
}
|
||||
}
|
||||
|
||||
addHighlightSignalsFromScoredLabels(best, "body", pred.BodyPartsPresent)
|
||||
@ -2297,6 +2310,19 @@ func preferAnalyzeSegmentLabel(a, b string) string {
|
||||
return a
|
||||
}
|
||||
|
||||
if strings.HasPrefix(a, "combo:") && strings.HasPrefix(b, "combo:") {
|
||||
if strings.Contains(a, "position:") && !strings.Contains(b, "position:") {
|
||||
return a
|
||||
}
|
||||
if strings.Contains(b, "position:") && !strings.Contains(a, "position:") {
|
||||
return b
|
||||
}
|
||||
if len(b) > len(a) {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// body: ist meist semantisch sauberer als detector:
|
||||
if strings.HasPrefix(a, "body:") && !strings.HasPrefix(b, "body:") {
|
||||
return a
|
||||
@ -2328,6 +2354,91 @@ func preferAnalyzeSegmentLabel(a, b string) string {
|
||||
return a
|
||||
}
|
||||
|
||||
func segmentLabelParts(label string) []string {
|
||||
label = strings.ToLower(strings.TrimSpace(label))
|
||||
if label == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if strings.HasPrefix(label, "combo:") {
|
||||
raw := strings.TrimPrefix(label, "combo:")
|
||||
parts := strings.Split(raw, "+")
|
||||
|
||||
out := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
part = strings.ToLower(strings.TrimSpace(part))
|
||||
if part != "" {
|
||||
out = append(out, part)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
return []string{label}
|
||||
}
|
||||
|
||||
func segmentPositionFromAnalyzeLabel(label string) string {
|
||||
for _, part := range segmentLabelParts(label) {
|
||||
part = strings.TrimSpace(part)
|
||||
part = strings.TrimPrefix(part, "position:")
|
||||
|
||||
if isKnownPositionLabel(part) {
|
||||
return part
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func segmentTagsFromAnalyzeLabel(label string) []string {
|
||||
parts := segmentLabelParts(label)
|
||||
if len(parts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]string, 0, len(parts))
|
||||
seen := map[string]bool{}
|
||||
|
||||
for _, part := range parts {
|
||||
part = strings.ToLower(strings.TrimSpace(part))
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Person nicht als Segment-Tag speichern.
|
||||
if isPersonSegmentLabel(part) {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(part, "position:") {
|
||||
pos := strings.TrimPrefix(part, "position:")
|
||||
if pos == "" || !isKnownPositionLabel(pos) {
|
||||
continue
|
||||
}
|
||||
|
||||
tag := "position:" + pos
|
||||
if !seen[tag] {
|
||||
seen[tag] = true
|
||||
out = append(out, tag)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if !seen[part] {
|
||||
seen[part] = true
|
||||
out = append(out, part)
|
||||
}
|
||||
}
|
||||
|
||||
if len(out) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeAnalyzeHits(in []analyzeHit) []analyzeHit {
|
||||
if len(in) == 0 {
|
||||
return []analyzeHit{}
|
||||
@ -2576,13 +2687,17 @@ func buildSegmentsFromAnalyzeHits(hits []analyzeHit, duration float64) []aiSegme
|
||||
continue
|
||||
}
|
||||
|
||||
label := strings.ToLower(strings.TrimSpace(hit.Label))
|
||||
|
||||
out = append(out, aiSegmentMeta{
|
||||
Label: strings.ToLower(strings.TrimSpace(hit.Label)),
|
||||
Label: label,
|
||||
StartSeconds: start,
|
||||
EndSeconds: end,
|
||||
DurationSeconds: end - start,
|
||||
Score: hit.Score,
|
||||
AutoSelected: true,
|
||||
Position: segmentPositionFromAnalyzeLabel(label),
|
||||
Tags: segmentTagsFromAnalyzeLabel(label),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2696,6 +2811,8 @@ func buildHighlightSegmentsFromAnalyzeHits(hits []analyzeHit, duration float64)
|
||||
DurationSeconds: end - start,
|
||||
Score: hit.Score,
|
||||
AutoSelected: true,
|
||||
Position: segmentPositionFromAnalyzeLabel(label),
|
||||
Tags: segmentTagsFromAnalyzeLabel(label),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -104,12 +104,14 @@ type videoMeta struct {
|
||||
}
|
||||
|
||||
type aiSegmentMeta struct {
|
||||
Label string `json:"label"`
|
||||
StartSeconds float64 `json:"startSeconds"`
|
||||
EndSeconds float64 `json:"endSeconds"`
|
||||
DurationSeconds float64 `json:"durationSeconds"`
|
||||
Score float64 `json:"score,omitempty"`
|
||||
AutoSelected bool `json:"autoSelected,omitempty"`
|
||||
Label string `json:"label"`
|
||||
StartSeconds float64 `json:"startSeconds"`
|
||||
EndSeconds float64 `json:"endSeconds"`
|
||||
DurationSeconds float64 `json:"durationSeconds"`
|
||||
Score float64 `json:"score,omitempty"`
|
||||
AutoSelected bool `json:"autoSelected,omitempty"`
|
||||
Position string `json:"position,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
type aiAnalysisMeta struct {
|
||||
|
||||
@ -289,12 +289,111 @@ function prettyAiLabel(value: unknown): string {
|
||||
return isAiLikeLabel(raw) ? titleCaseLabel(raw) : raw
|
||||
}
|
||||
|
||||
function rawSegmentLabelParts(value: unknown): string[] {
|
||||
const raw = String(value ?? '').trim().toLowerCase()
|
||||
if (!raw) return []
|
||||
|
||||
if (raw.startsWith('combo:')) {
|
||||
return raw
|
||||
.slice('combo:'.length)
|
||||
.split('+')
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
return [raw]
|
||||
}
|
||||
|
||||
function tagsFromSegmentLabel(value: unknown): string[] {
|
||||
const out: string[] = []
|
||||
|
||||
for (const part of rawSegmentLabelParts(value)) {
|
||||
const clean = part.trim()
|
||||
if (!clean) continue
|
||||
|
||||
if (clean.startsWith('position:')) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(`Position: ${label}`)
|
||||
continue
|
||||
}
|
||||
|
||||
if (clean.startsWith('body:')) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(label)
|
||||
continue
|
||||
}
|
||||
|
||||
if (clean.startsWith('object:')) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(label)
|
||||
continue
|
||||
}
|
||||
|
||||
if (clean.startsWith('clothing:')) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(label)
|
||||
continue
|
||||
}
|
||||
|
||||
if (clean.startsWith('detector:')) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(label)
|
||||
continue
|
||||
}
|
||||
|
||||
if (isKnownFrontendPositionLabel(clean)) {
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(`Position: ${label}`)
|
||||
continue
|
||||
}
|
||||
|
||||
const label = prettyAiLabel(clean)
|
||||
if (label) out.push(label)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
function isKnownFrontendPositionLabel(value: unknown): boolean {
|
||||
const label = String(value ?? '').trim().toLowerCase()
|
||||
|
||||
return [
|
||||
'missionary',
|
||||
'doggy',
|
||||
'doggystyle',
|
||||
'cowgirl',
|
||||
'reverse_cowgirl',
|
||||
'cunnilingus',
|
||||
'prone_bone',
|
||||
'standing',
|
||||
'standing_doggy',
|
||||
'spooning',
|
||||
'sitting',
|
||||
'facesitting',
|
||||
'handjob',
|
||||
'blowjob',
|
||||
'toy_play',
|
||||
'fingering',
|
||||
'69',
|
||||
'other',
|
||||
].includes(label)
|
||||
}
|
||||
|
||||
function segmentTitleFromRawLabel(raw: string): string {
|
||||
return prettyAiLabel(raw)
|
||||
}
|
||||
|
||||
function readSegmentTags(obj: Record<string, unknown>): string[] {
|
||||
const tags = readTags(obj)
|
||||
const position = typeof obj.position === 'string' && obj.position.trim()
|
||||
? `Position: ${prettyAiLabel(obj.position)}`
|
||||
: ''
|
||||
|
||||
const tags = [
|
||||
position,
|
||||
...tagsFromSegmentLabel(obj.label ?? obj.title ?? obj.category ?? obj.type ?? obj.kind ?? obj.name),
|
||||
...readTags(obj),
|
||||
]
|
||||
|
||||
const out: string[] = []
|
||||
|
||||
for (const tag of tags) {
|
||||
@ -303,7 +402,7 @@ function readSegmentTags(obj: Record<string, unknown>): string[] {
|
||||
out.push(tag)
|
||||
}
|
||||
|
||||
return out.slice(0, 6)
|
||||
return out.slice(0, 8)
|
||||
}
|
||||
|
||||
function prettyMaybeAiValue(key: string, value: string): string {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user