The NudeNet-thread got me thinking about an idea I had before. Its about ImageTags autotagging.
I think the NudeNet program can be used to do some basic work.
I wrote some code that does (on the first look) a quite reasonable job tagging images.
*** It works great for me, but please be careful! *******
There are 3 modes supported:
- Dommes mode (standard, iterate all dommes)
- Domme mode (iterate a specific domme)
- LocalImageTags mode
It can detect (Dome folders):
TagFace, TagBoobs, TagPussy, TagAss and TagFeet from the NudeNet Labels, and it will also guess the "dressing" (TagNaked, TagHalfDressed, TagFullyDressed) by counting covered and exposed labels. In addition it will add the tag TagCloseUp if the detected Bodypart fills more than 33% of the picture.
It can also detect (LocalImageTags):
TagBodyFace TagBodyTits TagBodyPussy TagBodyAss TagBodyFeet TagBodyCock
If it finds an ImageTags.txt or LocalImageTags.txt file, it will only add tags, not remove them. It will also only add a dressing-tag, if none exists.
by default it will create a backup of the ImageTags.txt file the FIRST time it it replaced. It will also create a backup file of the tags, so the resume function can work.
by default, it will skip folders that already have a backup file (resume = True)
Install nudenet module first: pip install --upgrade nudenetupdated
You will not need the docker stuff, only the nudenet module!
Usage: python TeaseAIAutoTager.py [options] <Folder>
Where <DommeFolders> is the top folder of all Dommes (containing the dommes with their image folders)
Options:
-l c:\path\to\TeaseAI\Images\System\LocalImageTags.txt file location (provide image folder, eg "hardcore"-folder)
-d <DommeFolder> Where <DommeFolder> is the top folder of a specific Domme
eg:
DommesTags: python TeaseAIAutoTager.py c:\TeaseAI\Images\Dommes
DommeTags: python TeaseAIAutoTager.py c:\TeaseAI\Images\Dommes\Brittany
LocalImageTags: python TeaseAIAutoTager.py -l c:\TeaseAI\Images\System\LocalImageTags.txt c:\TeaseAI\Images\Softcore
Speed is ~1-2 Sec/File
Code: Select all
# pip install --upgrade nudenet
# TeaseAIAutoTager.py
# Import module
import os
import sys
import PIL
import shutil
from nudenetupdated import NudeDetector
## DommeFolder (Folder which should contain folders which should contain images and can contain imagetags file)
##DommeFolder = "c:\\Dommes\\Brittany\\"
backup = True
resume = True
maxitems = 0 ## for LocalTags fille, as too many tags break performance. Set to 0 to deactivate
## Define minimum % of picture that needs to be filled with bodypart, or it will be filtered out
min_face_size = 0
min_breast_size = 0
min_ass_size = 0
min_pussy_size = 0
min_feet_size = 0
## Minimum size for a closeup, in % of picture
min_closeup_size_face = 30
min_closeup_size_breasts = 30
min_closeup_size_pussy = 5
min_closeup_size_ass = 30
min_closeup_size_feet = 10
dressings = ["TagFullyDressed","TagHalfDressed","TagGarmentCovering","TagHandsCovering","TagSeeThrough","TagNaked"]
def main(args):
localtags = False
domme_folder = False
if args[0] == "-l":
localtags = True
localtagsfile = args[1]
DommeFolder = args[2]
if not os.path.basename(localtagsfile) == "LocalImageTags.txt":
print ("wrong filename for LocalImageTags.txt")
exit(1)
elif args[0] == "-d":
# do only the domme folder provided
DommeFolder = args[1]
domme_folder = True
else:
## do all folders
DommeFolder = args[0]
if not os.path.isdir(DommeFolder):
print("ERROR: Folder "+DommeFolder+" not found")
exit(1)
if localtags == True:
tagsdata = get_tags_data(localtagsfile)
tagsdata = do_local_tags_folder (DommeFolder, tagsdata)
if backup and not os.path.isfile(localtagsfile+"-beforeNudeDetector") and os.path.isfile(localtagsfile):
os.rename(localtagsfile,localtagsfile+"-beforeNudeDetector")
write_tags(localtagsfile,tagsdata)
elif domme_folder:
do_domme_folder(os.path.join(DommeFolder))
else:
rootfolders = os.listdir(DommeFolder)
counter1 = 0
for r in rootfolders:
counter1 += 1
if os.path.isdir(os.path.join(DommeFolder,r)):
print("********")
print ("("+str(counter1)+"/"+str(len(rootfolders))+") "+"Starting DOMME "+os.path.join(r))
print("********")
do_domme_folder(os.path.join(DommeFolder,r))
def write_tags(tags_file, tagsdata):
with open(tags_file, "w") as tf:
for t in tagsdata:
tf.write(t+" "+" ".join(tagsdata[t])+"\n")
def get_tags_data(tagsfile):
tagsdata = {}
tagsinfile = None
if os.path.isfile(tagsfile):
with open(tagsfile, "r") as f:
for line in f:
# skip files without any tags
if len(line.split(" ")) < 2:
continue
filename = line.split(" ")[0].lower()
tags = line.split(" ")[1:]
tagsf = []
for t in tags:
## Remove newline
if t.strip() != "":
tagsf.append(t.strip())
tagsdata.update({filename: tagsf})
return tagsdata
def do_local_tags_folder(folder, tagsdata):
# Detected tags: TagBodyFace TagBodyTits TagBodyPussy TagBodyAss TagBodyFeet TagBodyCock
images = os.listdir(folder)
detector = NudeDetector()
if maxitems > 0:
images = images[0:maxitems]
imgcounter = 0
for img in images:
imgcounter += 1
imgfile = os.path.join(folder,img).lower()
try:
image = PIL.Image.open(imgfile)
width, height = image.size
size = (width * height) / 100
#print ("Image Size: "+str(width)+" * "+str(height)+" = "+str(size))
detected = detector.detect(imgfile)
image.close()
except:
if img != "ImageTags.txt" and img != "ImageTags.txt-beforeNudeDetector":
print ("Error: cannot identify image file: "+imgfile)
continue
detected_tags = set()
breast_size = 0
face_size = 0
ass_size = 0
pussy_size = 0
feet_size = 0
cock_size = 0
for d in detected:
#print(d)
if d['label'] == 'FACE_F':
face_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (face_size/size) > min_face_size:
detected_tags.add("TagBodyFace")
if d['label'] == 'COVERED_BREAST_F':
breast_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (breast_size/size) > min_breast_size:
detected_tags.add("TagBodyTits")
if d['label'] == 'EXPOSED_BREAST_F':
breast_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (breast_size/size) > min_breast_size:
detected_tags.add("TagBodyTits")
if d['label'] == 'COVERED_GENITALIA_F':
pussy_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (pussy_size/size) > min_pussy_size:
detected_tags.add("TagBodyPussy")
if d['label'] == 'EXPOSED_GENITALIA_F':
pussy_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (pussy_size/size) > min_pussy_size:
detected_tags.add("TagBodyPussy")
if d['label'] == 'COVERED_BUTTOCKS':
ass_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (ass_size/size) > min_ass_size:
detected_tags.add("TagBodyAss")
if d['label'] == 'EXPOSED_BUTTOCKS':
ass_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (ass_size/size) > min_ass_size:
detected_tags.add("TagBodyAss")
if d['label'] == 'EXPOSED_ANUS':
detected_tags.add("TagBodyAss")
if d['label'] == 'COVERED_FEET':
feet_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (feet_size/size) > min_feet_size:
detected_tags.add("TagBodyFeet")
if d['label'] == 'EXPOSED_FEET':
feet_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (feet_size/size) > min_feet_size:
detected_tags.add("TagBodyFeet")
if d['label'] == 'EXPOSED_GENITALIA_M':
cock_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (cock_size/size) > min_cock_size:
detected_tags.add("TagBodyCock")
#print closeup values, for debugging
#print ("face="+str(face_size/size)+" boobs="+str(breast_size/size)+" ass="+str(ass_size/size)+" pussy="+str(pussy_size/size))
if imgfile in tagsdata:
# add closeups
# only set if missing, dont overwrite
olddata = set(tagsdata[imgfile])
for tag in detected_tags:
olddata.add(tag)
if len(olddata) > 0:
tagsdata.update({imgfile: list(olddata)})
else:
del tagsdata[imgfile]
else:
if len(detected_tags) > 0:
tagsdata.update({imgfile: detected_tags})
if imgfile in tagsdata:
print ("("+str(imgcounter)+"/"+str(len(images))+") "+" ".join([imgfile]+list(tagsdata[imgfile])))
else:
print ("("+str(imgcounter)+"/"+str(len(images))+") "+imgfile+" no tags found, removing tags line")
return tagsdata
def do_domme_folder(folder):
folders = os.listdir(os.path.join(folder))
counter2 = 0
for f in folders:
counter2 += 1
if os.path.isdir(os.path.join(folder, f)):
print("********")
print ("("+str(counter2)+"/"+str(len(folders))+") "+"Starting dir "+os.path.join(folder,f))
print("********")
tagsfile = os.path.join(folder,f,"ImageTags.txt")
if resume == True:
backuptagsfile = tagsfile+"-beforeNudeDetector"
if os.path.isfile(backuptagsfile):
continue
tagsdata = get_tags_data(tagsfile)
tagsdata = do_folder(os.path.join(folder,f), tagsdata)
if backup and not os.path.isfile(tagsfile+"-beforeNudeDetector") and os.path.isfile(tagsfile):
os.rename(tagsfile,tagsfile+"-beforeNudeDetector")
write_tags(tagsfile, tagsdata)
if backup and not os.path.isfile(tagsfile+"-beforeNudeDetector") and os.path.isfile(tagsfile):
shutil.copyfile(tagsfile,tagsfile+"-beforeNudeDetector")
def do_folder(folder, tagsdata):
images = os.listdir(folder)
## Read ImageTags (if exists)
detector = NudeDetector()
imgcounter = 0
for img in images:
imgcounter += 1
imgfile = os.path.join(folder,img)
try:
image = PIL.Image.open(imgfile)
width, height = image.size
size = (width * height) / 100
#print ("Image Size: "+str(width)+" * "+str(height)+" = "+str(size))
detected = detector.detect(imgfile)
image.close()
except:
if img != "ImageTags.txt" and img != "ImageTags.txt-beforeNudeDetector":
print ("Error: cannot identify image file: "+imgfile)
continue
covered = 0
exposed = 0
detected_tags = set()
breast_size = 0
face_size = 0
ass_size = 0
feet_size = 0
pussy_size = 0
for d in detected:
#print(d)
if d['label'] == 'FACE_F':
face_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (face_size/size) > min_face_size:
detected_tags.add("TagFace")
if d['label'] == 'COVERED_BREAST_F':
breast_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (breast_size/size) > min_breast_size:
detected_tags.add("TagBoobs")
covered += 1
if d['label'] == 'EXPOSED_BREAST_F':
breast_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (breast_size/size) > min_breast_size:
detected_tags.add("TagBoobs")
exposed += 1
if d['label'] == 'COVERED_GENITALIA_F':
pussy_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (pussy_size/size) > min_pussy_size:
detected_tags.add("TagPussy")
covered += 1
if d['label'] == 'EXPOSED_GENITALIA_F':
pussy_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (pussy_size/size) > min_pussy_size:
detected_tags.add("TagPussy")
exposed += 1
if d['label'] == 'COVERED_BUTTOCKS':
ass_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (ass_size/size) > min_ass_size:
detected_tags.add("TagAss")
covered += 1
if d['label'] == 'EXPOSED_BUTTOCKS':
ass_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (ass_size/size) > min_ass_size:
detected_tags.add("TagAss")
exposed += 1
if d['label'] == 'EXPOSED_ANUS':
detected_tags.add("TagAss")
exposed += 1
if d['label'] == 'COVERED_FEET':
feet_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (feet_size/size) > min_feet_size:
detected_tags.add("TagFeet")
covered += 1
if d['label'] == 'EXPOSED_FEET':
feet_size += (d['box'][2]-d['box'][0])*(d['box'][3]-d['box'][1])
if (feet_size/size) > min_feet_size:
detected_tags.add("TagFeet")
exposed += 1
#print closeup values, for debugging
#print ("face="+str(face_size/size)+" boobs="+str(breast_size/size)+" ass="+str(ass_size/size)+" pussy="+str(pussy_size/size))
if (face_size/size) > min_closeup_size_face:
detected_tags.add("TagCloseUp")
if (breast_size/size) > min_closeup_size_breasts:
detected_tags.add("TagCloseUp")
if (ass_size/size) > min_closeup_size_ass:
detected_tags.add("TagCloseUp")
if (pussy_size/size) > min_closeup_size_pussy:
detected_tags.add("TagCloseUp")
if (feet_size/size) > min_closeup_size_feet:
detected_tags.add("TagCloseUp")
if img in tagsdata:
# add closeups
# only set if missing, dont overwrite
if not any(elem in tagsdata[img] for elem in dressings):
if exposed > 0:
if covered > 0:
detected_tags.add("TagHalfDressed")
else:
detected_tags.add("TagNaked")
else:
if covered > 0:
detected_tags.add("TagFullyDressed")
olddata = set(tagsdata[img])
for tag in detected_tags:
olddata.add(tag)
if len(olddata) > 0:
tagsdata.update({img: list(olddata)})
else:
del tagsdata[img]
else:
if exposed > 0:
if covered > 0:
detected_tags.add("TagHalfDressed")
else:
detected_tags.add("TagNaked")
else:
if covered > 0:
detected_tags.add("TagFullyDressed")
if len(detected_tags) > 0:
tagsdata.update({img: detected_tags})
if img in tagsdata:
print ("("+str(imgcounter)+"/"+str(len(images))+") "+" ".join([img]+list(tagsdata[img])))
else:
print ("("+str(imgcounter)+"/"+str(len(images))+") "+img+" no tags found, removing tag line")
return tagsdata
if __name__ == "__main__":
if len(sys.argv) < 2 or len(sys.argv) > 4:
print ("Usage: python "+sys.argv[0]+" [options] <DommeFolders>\n\tWhere <DommeFolders> is the top folder of all Dommes (containing the dommes with their image folders)\nOptions:\n-l c:\\path\\to\\TeaseAI\\Images\\System\\LocalImageTags.txt\tfile location (provide image folder, eg \"hardcore\"-folder)\n-d <DommeFolder> Where <DommeFolder> is the top folder of a specific Domme")
exit(1)
main(sys.argv[1:])