bugfixes
This commit is contained in:
parent
cf5888d9e5
commit
ec4fcea9b1
@ -373,7 +373,7 @@ func trainingPredictionToHighlightResults(pred TrainingPrediction) []NsfwFrameRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
comboScore := math.Min(positionScore, score)
|
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{}
|
best := map[string]highlightSignal{}
|
||||||
|
|
||||||
sexPosition := strings.ToLower(strings.TrimSpace(pred.SexPosition))
|
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)
|
addHighlightSignalsFromScoredLabels(best, "body", pred.BodyPartsPresent)
|
||||||
@ -2297,6 +2310,19 @@ func preferAnalyzeSegmentLabel(a, b string) string {
|
|||||||
return a
|
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:
|
// body: ist meist semantisch sauberer als detector:
|
||||||
if strings.HasPrefix(a, "body:") && !strings.HasPrefix(b, "body:") {
|
if strings.HasPrefix(a, "body:") && !strings.HasPrefix(b, "body:") {
|
||||||
return a
|
return a
|
||||||
@ -2328,6 +2354,91 @@ func preferAnalyzeSegmentLabel(a, b string) string {
|
|||||||
return a
|
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 {
|
func mergeAnalyzeHits(in []analyzeHit) []analyzeHit {
|
||||||
if len(in) == 0 {
|
if len(in) == 0 {
|
||||||
return []analyzeHit{}
|
return []analyzeHit{}
|
||||||
@ -2576,13 +2687,17 @@ func buildSegmentsFromAnalyzeHits(hits []analyzeHit, duration float64) []aiSegme
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label := strings.ToLower(strings.TrimSpace(hit.Label))
|
||||||
|
|
||||||
out = append(out, aiSegmentMeta{
|
out = append(out, aiSegmentMeta{
|
||||||
Label: strings.ToLower(strings.TrimSpace(hit.Label)),
|
Label: label,
|
||||||
StartSeconds: start,
|
StartSeconds: start,
|
||||||
EndSeconds: end,
|
EndSeconds: end,
|
||||||
DurationSeconds: end - start,
|
DurationSeconds: end - start,
|
||||||
Score: hit.Score,
|
Score: hit.Score,
|
||||||
AutoSelected: true,
|
AutoSelected: true,
|
||||||
|
Position: segmentPositionFromAnalyzeLabel(label),
|
||||||
|
Tags: segmentTagsFromAnalyzeLabel(label),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2696,6 +2811,8 @@ func buildHighlightSegmentsFromAnalyzeHits(hits []analyzeHit, duration float64)
|
|||||||
DurationSeconds: end - start,
|
DurationSeconds: end - start,
|
||||||
Score: hit.Score,
|
Score: hit.Score,
|
||||||
AutoSelected: true,
|
AutoSelected: true,
|
||||||
|
Position: segmentPositionFromAnalyzeLabel(label),
|
||||||
|
Tags: segmentTagsFromAnalyzeLabel(label),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,8 @@ type aiSegmentMeta struct {
|
|||||||
DurationSeconds float64 `json:"durationSeconds"`
|
DurationSeconds float64 `json:"durationSeconds"`
|
||||||
Score float64 `json:"score,omitempty"`
|
Score float64 `json:"score,omitempty"`
|
||||||
AutoSelected bool `json:"autoSelected,omitempty"`
|
AutoSelected bool `json:"autoSelected,omitempty"`
|
||||||
|
Position string `json:"position,omitempty"`
|
||||||
|
Tags []string `json:"tags,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type aiAnalysisMeta struct {
|
type aiAnalysisMeta struct {
|
||||||
|
|||||||
@ -289,12 +289,111 @@ function prettyAiLabel(value: unknown): string {
|
|||||||
return isAiLikeLabel(raw) ? titleCaseLabel(raw) : raw
|
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 {
|
function segmentTitleFromRawLabel(raw: string): string {
|
||||||
return prettyAiLabel(raw)
|
return prettyAiLabel(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
function readSegmentTags(obj: Record<string, unknown>): string[] {
|
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[] = []
|
const out: string[] = []
|
||||||
|
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
@ -303,7 +402,7 @@ function readSegmentTags(obj: Record<string, unknown>): string[] {
|
|||||||
out.push(tag)
|
out.push(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.slice(0, 6)
|
return out.slice(0, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
function prettyMaybeAiValue(key: string, value: string): string {
|
function prettyMaybeAiValue(key: string, value: string): string {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user