From 2ada5fb5596c01d1530fc4be17b724a5d37225ae Mon Sep 17 00:00:00 2001 From: mike Date: Sat, 27 Jun 2026 23:01:16 +0200 Subject: [PATCH] reorder --- backlog.md | 11 +- tour-comfy/car.html | 222 +++++++++++++++++++++++++++------------ tour-comfy/database.py | 16 +-- tour-comfy/edit_api.py | 43 ++++++-- tour-comfy/embeddings.py | 30 ++++-- tour-comfy/poses.md | 39 +++++-- tour-comfy/trash.html | 24 +++++ tour-comfy/watcher.py | 2 +- 8 files changed, 282 insertions(+), 105 deletions(-) diff --git a/backlog.md b/backlog.md index f9b05cb..a9c753a 100644 --- a/backlog.md +++ b/backlog.md @@ -63,7 +63,9 @@ Scenery: - The UI wants to car.html:2817 GET file:///mnt/zim/tour-comfy/output/_turntable/up_34e48ffb/turntable.jpg?t=1782562827857 net::ERR_FILE_NOT_FOUND, often want to show the wireframe - pose - Jun 27 14:38:03 MIKE bash[3607206]: INFO: 127.0.0.1:53442 - "GET /output/_turntable/up_a1104f04/views/view_023_345deg.png HTTP/1.1" 304 Not Modified those files should be statically served from filesystem, not via server - Check face similarity in a group of images. -- +- implement a tag-system for images, will be used to filter, group, sort and search images. Obvious tags are VISIBLE, ARCHIVED, LIKE, DISLIKE, RATED, GROUP_ANCHOR, GROUP_MEMBER, BACKGROUND etc.. +- mark image as source +- introduce multiple filmstrips. . ## refine - when refresh page, we lose track of current jobs running. @@ -88,4 +90,9 @@ group-names.json names.json groups.json config -videos \ No newline at end of file +videos + +# generieke stappen +1) 3ref image HQ detail +2) 3ref image MERGE +3) 3ref straight on- head-on - looking viewer \ No newline at end of file diff --git a/tour-comfy/car.html b/tour-comfy/car.html index f7d5386..93706d5 100644 --- a/tour-comfy/car.html +++ b/tour-comfy/car.html @@ -2220,20 +2220,171 @@ // --- HYDRATION_START --- const PRELOADED_IMAGES = [ + "20260627_201629_7_20260627_201343_image.nobg.png", + "20260627_201629_7_20260627_201343_image.png", + "20260627_225051_mr_image.png", + "20260627_224340_mr_image.png", + "20260627_224013_mr_image.png", + "20260627_223316_image.png", + "20260627_223304_image.png", + "20260627_223252_image.png", + "20260627_223028_image.png", + "20260627_223017_image.png", + "20260627_223005_image.png", + "20260627_222926_image.png", + "20260627_222915_image.png", + "20260627_222904_image.png", + "20260627_222806_mr_image.png", + "20260627_222321_image.png", + "20260627_222310_image.png", + "20260627_222259_image.png", + "20260627_222112_mr_image.png", + "20260627_222047_mr_image.png", + "20260627_222015_mr_image.png", + "20260626_034949_pose_jb.nobg.png", + "cg_0ed9a15a_face.png", + "_turntable/cg_7c7b22c9/views/view_022_330deg.png", + "20260618_015124_20260618_010617_20260615_153426_img_12.nobg.png", + "_turntable/cg_5991f3f2/views/view_002_030deg.png", + "_turntable/cg_5991f3f2/views/view_022_330deg.png", + "_turntable/up_6ed4293c/views/view_021_315deg.png", + "_turntable/up_6ed4293c/views/view_020_300deg.png", + "20260627_213910_best_02_person_0.874_2026-06-27_12-18-49.png", + "20260627_213840_best_02_person_0.874_2026-06-27_12-18-49.png", + "20260627_213816_best_01_person_0.874_2026-06-27_12-18-49.png", + "20260627_213756_best_01_person_0.874_2026-06-27_12-18-49.png", + "20260627_213743_best_01_person_0.874_2026-06-27_12-18-49.png", + "20260627_213727_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213711_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213626_best_02_person_0.874_2026-06-27_12-18-49.png", + "20260627_213613_best_01_person_0.874_2026-06-27_12-18-49.png", + "20260627_213559_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213517_image.png", + "20260627_213504_image.png", + "20260627_213451_image.png", + "20260627_213241_12_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_213227_11_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "_turntable/cg_74544975/views/view_023_345deg.png", + "20260627_213215_10_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "_turntable/cg_74544975/views/view_022_330deg.png", + "_turntable/cg_74544975/views/view_021_315deg.png", + "_turntable/cg_74544975/views/view_020_300deg.png", + "_turntable/cg_74544975/views/view_019_285deg.png", + "_turntable/cg_74544975/views/view_018_270deg.png", + "20260627_213202_9_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_213149_8_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "_turntable/cg_74544975/views/view_004_060deg.png", + "_turntable/up_6ed4293c/views/view_019_285deg.png", + "_turntable/cg_74544975/views/view_001_015deg.png", + "_turntable/cg_74544975/views/view_000_000deg.png", + "20260627_213102_12_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213037_11_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_213013_10_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212949_9_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212937_3_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_212925_8_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212913_2_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_212901_7_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212848_1_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_212836_6_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212824_0_20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg.png", + "20260627_212814_best_02_person_0.874_2026-06-27_20-05-05.png", + "20260627_212814_best_02_person_0.874_2026-06-27_20-05-05.jpg", + "20260627_212814_best_01_person_0.874_2026-06-27_20-05-05.png", + "20260627_212814_best_00_person_0.874_2026-06-27_20-05-05.png", + "20260627_212814_best_00_person_0.874_2026-06-27_20-05-05.jpg", + "20260627_212812_5_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212803_best_01_person_0.874_2026-06-27_20-05-05.jpg", + "20260627_212800_4_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212748_3_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212735_2_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212726_best_02_person_0.874_2026-06-27_12-18-49.png", + "20260627_212726_best_01_person_0.874_2026-06-27_12-18-49.png", + "20260627_212726_best_01_person_0.874_2026-06-27_12-18-49.jpg", + "20260627_212726_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212726_best_00_person_0.874_2026-06-27_12-18-49.jpg", + "20260627_212723_1_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212710_0_20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "20260627_212658_best_00_person_0.874_2026-06-27_12-18-49.png", + "_turntable/up_6ed4293c/views/view_018_270deg.png", + "_turntable/up_6ed4293c/views/view_017_255deg.png", + "_turntable/up_6ed4293c/views/view_016_240deg.png", + "_turntable/up_6ed4293c/views/view_015_225deg.png", + "_turntable/up_6ed4293c/views/view_014_210deg.png", + "_turntable/up_6ed4293c/views/view_013_195deg.png", + "_turntable/up_6ed4293c/views/view_012_180deg.png", + "_turntable/up_6ed4293c/views/view_011_165deg.png", + "_turntable/up_6ed4293c/views/view_010_150deg.png", + "_turntable/up_6ed4293c/views/view_009_135deg.png", + "_turntable/up_6ed4293c/views/view_008_120deg.png", + "_turntable/up_6ed4293c/views/view_007_105deg.png", + "_turntable/up_6ed4293c/views/view_006_090deg.png", + "_turntable/up_6ed4293c/views/view_005_075deg.png", + "_turntable/up_6ed4293c/views/view_004_060deg.png", + "_turntable/up_6ed4293c/views/view_003_045deg.png", + "_turntable/up_6ed4293c/views/view_002_030deg.png", + "_turntable/up_6ed4293c/views/view_001_015deg.png", "_turntable/up_6ed4293c/views/view_000_000deg.png", + "20260627_204815_image.png", + "20260627_204804_image.png", + "20260627_204756_image.png", + "_turntable/cg_f85e7ae1/views/view_023_345deg.png", + "_turntable/cg_f85e7ae1/views/view_013_195deg.png", + "_turntable/cg_f85e7ae1/views/view_012_180deg.png", + "_turntable/cg_f85e7ae1/views/view_010_150deg.png", + "_turntable/cg_f85e7ae1/views/view_001_015deg.png", + "_turntable/cg_f85e7ae1/views/view_000_000deg.png", + "_turntable/cg_75340e8e/views/view_017_255deg.png", + "_turntable/cg_75340e8e/views/view_016_240deg.png", + "_turntable/cg_75340e8e/views/view_014_210deg.png", + "_turntable/cg_75340e8e/views/view_013_195deg.png", + "_turntable/cg_75340e8e/views/view_012_180deg.png", + "_turntable/cg_75340e8e/views/view_011_165deg.png", + "_turntable/cg_75340e8e/views/view_010_150deg.png", + "_turntable/cg_75340e8e/views/view_009_135deg.png", + "_turntable/cg_75340e8e/views/view_008_120deg.png", + "_turntable/cg_75340e8e/views/view_007_105deg.png", + "_turntable/cg_75340e8e/views/view_023_345deg.png", + "_turntable/cg_75340e8e/views/view_001_015deg.png", + "_turntable/cg_75340e8e/views/view_000_000deg.png", + "20260627_203706_11_20260627_200330_image.png", + "up_7b6eaabb_face.png", + "20260627_203654_11_20260627_200330_image.png", + "20260627_203642_11_20260627_200330_image.png", + "20260627_203626_image.png", + "20260627_203607_image.png", + "20260627_203549_image.png", + "20260627_203531_Screenshot_From_2026-06-27_20-04-11.png", + "20260627_203514_Screenshot_From_2026-06-27_20-04-11.png", + "20260627_203459_Screenshot_From_2026-06-27_20-04-11.png", + "20260627_203349_image.png", + "20260627_203337_image.png", + "20260627_203324_image.png", + "20260627_203312_image.png", + "20260627_203300_image.png", + "20260627_203247_image.png", + "up_c8be3aa7_face.png", + "20260627_203235_Screenshot_From_2026-06-27_19-59-43.png", + "20260627_203223_Screenshot_From_2026-06-27_19-59-43.png", + "20260627_203211_Screenshot_From_2026-06-27_19-59-43.png", + "20260627_203127_image.png", + "20260627_203105_Screenshot_From_2026-06-27_19-59-43.png", + "20260627_203054_Screenshot_From_2026-06-27_20-04-11.png", + "20260627_203044_image.png", + "20260627_203032_image.png", + "_turntable/up_c8be3aa7/views/view_002_030deg.png", + "_turntable/up_c8be3aa7/views/view_003_045deg.png", "20260627_201807_12_20260627_201343_image.png", "20260627_201753_Screenshot_From_2026-06-27_12-32-39.png", "20260627_201751_11_20260627_201343_image.png", "20260627_201733_10_20260627_201343_image.png", "20260627_201711_9_20260627_201343_image.png", "20260627_201648_8_20260627_201343_image.png", - "20260627_201629_7_20260627_201343_image.png", "20260627_201622_Screenshot_From_2026-06-27_20-04-55.png", "20260627_201614_Screenshot_From_2026-06-27_20-04-11.png", - "20260627_201608_6_20260627_201343_image.png", "20260627_201558_Screenshot_From_2026-06-27_19-59-43.png", "20260627_201548_5_20260627_201343_image.png", - "20260627_201525_4_20260627_201343_image.png", "20260627_201518_image.png", "20260627_201500_3_20260627_201343_image.png", "20260627_201439_2_20260627_201343_image.png", @@ -2244,16 +2395,10 @@ "_turntable/up_c8be3aa7/views/view_006_090deg.png", "_turntable/up_c8be3aa7/views/view_005_075deg.png", "_turntable/up_c8be3aa7/views/view_004_060deg.png", - "_turntable/up_c8be3aa7/views/view_003_045deg.png", - "_turntable/up_c8be3aa7/views/view_002_030deg.png", - "20260627_200801_12_20260627_200330_image.png", "_turntable/up_c8be3aa7/views/view_001_015deg.png", "20260627_200711_11_20260627_200330_image.png", "20260627_200632_9_20260627_200330_image.png", - "20260627_200534_6_20260627_200330_image.png", "20260627_200506_image.png", - "20260627_200458_4_20260627_200330_image.png", - "20260627_200440_3_20260627_200330_image.png", "20260627_200422_2_20260627_200330_image.png", "20260627_200414_image.png", "20260627_200405_1_20260627_200330_image.png", @@ -2454,31 +2599,17 @@ "_turntable/cg_e964fb19/views/view_002_030deg.png", "_turntable/cg_e964fb19/views/view_001_015deg.png", "_turntable/cg_e964fb19/views/view_000_000deg.png", - "_turntable/cg_75340e8e/views/view_023_345deg.png", "_turntable/cg_75340e8e/views/view_022_330deg.png", "_turntable/cg_75340e8e/views/view_021_315deg.png", "_turntable/cg_75340e8e/views/view_020_300deg.png", "_turntable/cg_75340e8e/views/view_019_285deg.png", "_turntable/cg_75340e8e/views/view_018_270deg.png", - "_turntable/cg_75340e8e/views/view_017_255deg.png", - "_turntable/cg_75340e8e/views/view_016_240deg.png", "_turntable/cg_75340e8e/views/view_015_225deg.png", - "_turntable/cg_75340e8e/views/view_014_210deg.png", - "_turntable/cg_75340e8e/views/view_013_195deg.png", - "_turntable/cg_75340e8e/views/view_012_180deg.png", - "_turntable/cg_75340e8e/views/view_011_165deg.png", - "_turntable/cg_75340e8e/views/view_010_150deg.png", - "_turntable/cg_75340e8e/views/view_009_135deg.png", - "_turntable/cg_75340e8e/views/view_008_120deg.png", - "_turntable/cg_75340e8e/views/view_007_105deg.png", "_turntable/cg_75340e8e/views/view_006_090deg.png", "_turntable/cg_75340e8e/views/view_005_075deg.png", "_turntable/cg_75340e8e/views/view_004_060deg.png", "_turntable/cg_75340e8e/views/view_003_045deg.png", "_turntable/cg_75340e8e/views/view_002_030deg.png", - "_turntable/cg_75340e8e/views/view_001_015deg.png", - "_turntable/cg_75340e8e/views/view_000_000deg.png", - "_turntable/cg_f85e7ae1/views/view_023_345deg.png", "_turntable/cg_f85e7ae1/views/view_022_330deg.png", "_turntable/cg_f85e7ae1/views/view_021_315deg.png", "_turntable/cg_f85e7ae1/views/view_020_300deg.png", @@ -2488,10 +2619,7 @@ "_turntable/cg_f85e7ae1/views/view_016_240deg.png", "_turntable/cg_f85e7ae1/views/view_015_225deg.png", "_turntable/cg_f85e7ae1/views/view_014_210deg.png", - "_turntable/cg_f85e7ae1/views/view_013_195deg.png", - "_turntable/cg_f85e7ae1/views/view_012_180deg.png", "_turntable/cg_f85e7ae1/views/view_011_165deg.png", - "_turntable/cg_f85e7ae1/views/view_010_150deg.png", "_turntable/cg_f85e7ae1/views/view_009_135deg.png", "_turntable/cg_f85e7ae1/views/view_008_120deg.png", "_turntable/cg_f85e7ae1/views/view_007_105deg.png", @@ -2500,8 +2628,6 @@ "_turntable/cg_f85e7ae1/views/view_004_060deg.png", "_turntable/cg_f85e7ae1/views/view_003_045deg.png", "_turntable/cg_f85e7ae1/views/view_002_030deg.png", - "_turntable/cg_f85e7ae1/views/view_001_015deg.png", - "_turntable/cg_f85e7ae1/views/view_000_000deg.png", "_turntable/up_c31bb439/views/view_023_345deg.png", "_turntable/up_c31bb439/views/view_022_330deg.png", "_turntable/up_c31bb439/views/view_021_315deg.png", @@ -2550,12 +2676,6 @@ "_turntable/cg_4671b6c4/views/view_002_030deg.png", "_turntable/cg_4671b6c4/views/view_001_015deg.png", "_turntable/cg_4671b6c4/views/view_000_000deg.png", - "_turntable/cg_74544975/views/view_023_345deg.png", - "_turntable/cg_74544975/views/view_022_330deg.png", - "_turntable/cg_74544975/views/view_021_315deg.png", - "_turntable/cg_74544975/views/view_020_300deg.png", - "_turntable/cg_74544975/views/view_019_285deg.png", - "_turntable/cg_74544975/views/view_018_270deg.png", "_turntable/cg_74544975/views/view_017_255deg.png", "_turntable/cg_74544975/views/view_016_240deg.png", "_turntable/cg_74544975/views/view_015_225deg.png", @@ -2569,11 +2689,8 @@ "_turntable/cg_74544975/views/view_007_105deg.png", "_turntable/cg_74544975/views/view_006_090deg.png", "_turntable/cg_74544975/views/view_005_075deg.png", - "_turntable/cg_74544975/views/view_004_060deg.png", "_turntable/cg_74544975/views/view_003_045deg.png", "_turntable/cg_74544975/views/view_002_030deg.png", - "_turntable/cg_74544975/views/view_001_015deg.png", - "_turntable/cg_74544975/views/view_000_000deg.png", "_turntable/cg_73e141fa/views/view_023_345deg.png", "_turntable/cg_73e141fa/views/view_022_330deg.png", "_turntable/cg_73e141fa/views/view_021_315deg.png", @@ -3616,7 +3733,6 @@ "_turntable/cg_58c0891c/views/view_001_015deg.png", "_turntable/cg_58c0891c/views/view_000_000deg.png", "_turntable/cg_5991f3f2/views/view_023_345deg.png", - "_turntable/cg_5991f3f2/views/view_022_330deg.png", "_turntable/cg_5991f3f2/views/view_021_315deg.png", "_turntable/cg_5991f3f2/views/view_020_300deg.png", "_turntable/cg_5991f3f2/views/view_019_285deg.png", @@ -3636,7 +3752,6 @@ "_turntable/cg_5991f3f2/views/view_005_075deg.png", "_turntable/cg_5991f3f2/views/view_004_060deg.png", "_turntable/cg_5991f3f2/views/view_003_045deg.png", - "_turntable/cg_5991f3f2/views/view_002_030deg.png", "_turntable/cg_5991f3f2/views/view_001_015deg.png", "_turntable/cg_5991f3f2/views/view_000_000deg.png", "_turntable/out4.png/views/view_023_345deg.png", @@ -4032,9 +4147,7 @@ "_turntable/cg_2afca8fc/views/view_003_045deg.png", "_turntable/cg_2afca8fc/views/view_002_030deg.png", "_turntable/cg_2afca8fc/views/view_000_000deg.png", - "_turntable/cg_7c7b22c9/turntable.mp4", "_turntable/cg_7c7b22c9/views/view_023_345deg.png", - "_turntable/cg_7c7b22c9/views/view_022_330deg.png", "_turntable/cg_7c7b22c9/views/view_021_315deg.png", "_turntable/cg_7c7b22c9/views/view_020_300deg.png", "_turntable/cg_7c7b22c9/views/view_019_285deg.png", @@ -4421,7 +4534,6 @@ "_turntable/cg_e79533a4/views/view_002_030deg.png", "_turntable/cg_e79533a4/views/view_001_015deg.png", "_turntable/cg_e79533a4/views/view_000_000deg.png", - "_turntable/b1.png/turntable.mp4", "_turntable/b1.png/views/view_023_345deg.png", "_turntable/b1.png/views/view_022_330deg.png", "_turntable/b1.png/views/view_021_315deg.png", @@ -4477,9 +4589,7 @@ "20260626_040655_sc_pad_20260626_034830_jb.nobg.png", "20260626_040550_sc_pad_20260626_034830_jb.nobg.png", "20260626_035131_pose_pad_20260626_034830_jb.nobg.png", - "cg_0ed9a15a_face.png", "20260626_035101_pad_20260626_034830_jb.nobg.png", - "20260626_034949_pose_jb.nobg.png", "20260626_034830_jb.nobg.png", "20260626_034830_jb.png", "20260626_034708_jb.png", @@ -4488,7 +4598,6 @@ "20260626_031810_1_20260618_050846_img_4.nobg.png", "20260618_050923_2_20260618_050846_img_4.nobg.png", "20260626_030908_1_20260618_050846_img_4.nobg.png", - "20260626_031833_1_20260618_050846_img_4.png", "20260626_031821_1_20260618_050846_img_4.png", "20260626_031810_1_20260618_050846_img_4.png", "20260626_031759_jb1.png", @@ -4858,7 +4967,6 @@ "20260624_160124_1_20260619_040135_image.png", "20260624_160113_1_20260619_040135_image.png", "20260624_160102_1_20260619_040135_image.png", - "20260624_154905_img_72.png", "20260624_154852_img_72.png", "20260624_154840_img_72.png", "20260624_154821_img_72.png", @@ -4866,7 +4974,6 @@ "20260624_154746_img_72.png", "20260624_154729_img_72.png", "20260624_154712_img_72.png", - "20260624_154655_img_72.png", "20260624_154639_img_72.png", "20260624_154548_img_72.png", "20260624_154536_img_72.png", @@ -4879,13 +4986,10 @@ "cg_b7e71d34_face.png", "20260624_154236_img_72.png", "20260624_154125_img_72.png", - "20260624_154040_img_72.png", "20260624_153940_img_72.png", "20260624_153831_img_72.png", "20260624_153614_Screenshot_From_2026-06-17_07-41-27.png", - "20260624_153433_Screenshot_From_2026-06-17_07-41-27.png", "20260624_153417_Screenshot_From_2026-06-17_07-41-27.png", - "20260624_153400_Screenshot_From_2026-06-17_07-41-27.png", "20260624_153344_Screenshot_From_2026-06-17_07-41-27.png", "20260624_153311_Screenshot_From_2026-06-17_07-41-27.png", "20260624_153102_Screenshot_From_2026-06-17_07-41-27.png", @@ -4957,7 +5061,6 @@ "20260624_140813_Screenshot_From_2026-06-17_07-43-19.png", "20260624_140807_Screenshot_From_2026-06-17_07-41-27.png", "20260624_140605_image.png", - "20260624_140549_image.png", "20260624_140532_image.png", "20260624_140221_image.png", "20260624_140129_image.png", @@ -5586,14 +5689,10 @@ "20260622_041306_image.png", "20260622_041253_image.png", "20260622_040911_b1.png", - "20260622_040858_b1.png", - "20260622_040846_b1.png", "20260622_040727_b1.png", "20260622_040702_b1.png", - "20260622_040649_b1.png", "20260622_040636_b1.png", "20260622_040347_b1.png", - "20260622_040141_b1.png", "20260622_035945_b1.png", "20260622_034529_b1.png", "20260622_033840_b1.png", @@ -5868,8 +5967,6 @@ "20260620_014646_image.png", "20260620_014349_image.png", "20260620_014239_img_77.png", - "20260627_145331_dup_20260618_011550_20260616_023209_img_51.png", - "20260627_145407_dup_20260618_011550_20260616_023209_img_51.png", "20260620_003901_2_20260619_175210_image.png", "20260620_003844_2_20260619_175210_image.png", "20260620_003828_2_20260619_175210_image.png", @@ -5920,10 +6017,8 @@ "20260619_224737_img_14.png", "20260619_224557_img_81.png", "20260619_224542_img_35.png", - "20260619_224219_img_12.png", "20260619_224133_img_87.png", "20260619_224007_img_31.png", - "20260619_223940_img_75.png", "20260619_223856_img_37.png", "20260619_223812_img_57.png", "20260619_223757_img_82.png", @@ -6114,7 +6209,6 @@ "20260619_041555_1_20260619_040135_image.png", "20260619_041544_1_20260619_040135_image.png", "20260619_041533_1_20260619_040135_image.png", - "20260619_041522_1_20260619_040135_image.png", "20260619_041511_1_20260619_040135_image.png", "20260619_041500_1_20260619_040135_image.png", "20260619_041449_1_20260619_040135_image.png", @@ -6372,7 +6466,6 @@ "20260618_125809_1_20260618_125748_image.png", "20260618_125758_0_20260618_125748_image.png", "20260618_125748_image.png", - "20260618_125415_6_20260618_125217_image.png", "20260618_125358_5_20260618_125217_image.png", "20260618_125340_4_20260618_125217_image.png", "20260618_125323_3_20260618_125217_image.png", @@ -6431,7 +6524,6 @@ "20260618_052548_1_20260618_052526_image.png", "20260618_052537_0_20260618_052526_image.png", "20260618_052526_image.png", - "20260618_051040_8_20260618_050846_img_4.png", "20260618_051029_7_20260618_050846_img_4.png", "20260618_051006_5_20260618_050846_img_4.png", "20260618_050923_2_20260618_050846_img_4.png", @@ -6442,18 +6534,14 @@ "20260618_015156_20260618_010700_Pasted image (4).png", "20260618_015145_20260618_010627_jb3.png", "20260618_015135_20260618_011424_20260618_004356_bb_01.png", - "20260618_015124_20260618_010617_20260615_153426_img_12.png", "20260618_015113_20260618_004952_jb.png", "20260618_015030_20260618_004858_p12.png", "20260618_015019_20260618_010638_b1.png", "20260618_015008_20260618_011445_20260618_004450_20260617_074413_img_73.png", "20260618_013512_Pasted image (9).png", "20260618_013502_kk563t.png", - "20260618_011633_t159zr-1.png", "20260618_011612_20260616_003803_img_14.png", - "20260618_011528_20260617_074613_img_75.png", "20260618_011517_20260618_002014_20260616_020035_img_36.png", - "20260618_011507_20260617_134615_img_86.png", "20260618_011456_20260618_004439_20260617_005512_img_60.png", "20260618_011445_20260618_004450_20260617_074413_img_73.png", "20260618_011434_20260618_004847_20260615_150812_img_19_2.png", @@ -6462,7 +6550,6 @@ "20260618_010710_p12-2.png", "20260618_010700_Pasted image (4).png", "20260618_010627_jb3.png", - "20260618_010617_20260615_153426_img_12.png", "20260618_004952_jb.png", "20260618_004941_out7.png", "20260618_004930_20260617_134041_img_84.png", @@ -6498,7 +6585,6 @@ "20260617_133411_img_79.png", "20260617_133154_img_78.png", "20260617_133129_img_77.png", - "20260617_074613_img_75.png", "20260617_074413_img_73.png", "20260617_074223_img_72.png", "20260617_005512_img_60.png", diff --git a/tour-comfy/database.py b/tour-comfy/database.py index dcec164..e3765d8 100644 --- a/tour-comfy/database.py +++ b/tour-comfy/database.py @@ -112,6 +112,7 @@ def migrate_schema(): "ALTER TABLE person ADD COLUMN IF NOT EXISTS faceswap_source_video TEXT", "ALTER TABLE person ADD COLUMN IF NOT EXISTS archived BOOLEAN DEFAULT FALSE", "ALTER TABLE person ADD COLUMN IF NOT EXISTS face_embedding vector(512)", + "ALTER TABLE person ADD COLUMN IF NOT EXISTS is_source BOOLEAN DEFAULT FALSE", ]: cur.execute(sql) conn.commit() @@ -124,7 +125,7 @@ def upsert_person(filename, filepath=None, name=None, group_id=None, tags=None, sort_order=None, group_name=None, hidden=None, has_background=None, source_refs=None, has_clothing=None, content_type=None, faceswap_source_video=None, archived=None, - face_embedding=None): + face_embedding=None, is_source=None): conn = get_db_connection() cur = conn.cursor() face_embedding_str = ("[" + ",".join(map(str, face_embedding)) + "]") if face_embedding is not None else None @@ -133,8 +134,8 @@ def upsert_person(filename, filepath=None, name=None, group_id=None, tags=None, INSERT INTO person (filename, filepath, name, group_id, tags, embedding, clip_description, prompt, pose, sort_order, group_name, hidden, has_background, source_refs, has_clothing, - content_type, faceswap_source_video, archived, face_embedding) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + content_type, faceswap_source_video, archived, face_embedding, is_source) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON CONFLICT (filename) DO UPDATE SET filepath = COALESCE(EXCLUDED.filepath, person.filepath), name = COALESCE(EXCLUDED.name, person.name), @@ -153,12 +154,13 @@ def upsert_person(filename, filepath=None, name=None, group_id=None, tags=None, content_type = COALESCE(EXCLUDED.content_type, person.content_type), faceswap_source_video = COALESCE(EXCLUDED.faceswap_source_video, person.faceswap_source_video), archived = COALESCE(EXCLUDED.archived, person.archived), - face_embedding = COALESCE(EXCLUDED.face_embedding, person.face_embedding); + face_embedding = COALESCE(EXCLUDED.face_embedding, person.face_embedding), + is_source = COALESCE(EXCLUDED.is_source, person.is_source); """, (filename, filepath, name, group_id, json.dumps(tags) if tags else None, embedding, clip_description, prompt, pose, sort_order, group_name, hidden, has_background, source_refs, has_clothing, - content_type, faceswap_source_video, archived, face_embedding_str)) + content_type, faceswap_source_video, archived, face_embedding_str, is_source)) conn.commit() finally: cur.close() @@ -206,7 +208,7 @@ def get_person(filename): cur.execute(""" SELECT name, group_id, tags, embedding, clip_description, filepath, prompt, pose, sort_order, group_name, hidden, has_background, source_refs, - has_clothing + has_clothing, is_source FROM person WHERE filename = %s """, (filename,)) return cur.fetchone() @@ -222,7 +224,7 @@ def list_persons(include_archived=False): cur.execute(f""" SELECT filename, name, group_id, clip_description, prompt, pose, sort_order, group_name, hidden, has_background, source_refs, - has_clothing, content_type, faceswap_source_video, archived + has_clothing, content_type, faceswap_source_video, archived, is_source FROM person {where} """) diff --git a/tour-comfy/edit_api.py b/tour-comfy/edit_api.py index 2f243c9..c6c2281 100644 --- a/tour-comfy/edit_api.py +++ b/tour-comfy/edit_api.py @@ -210,13 +210,21 @@ def _run_consistency_check(): persons = database.list_persons(include_archived=True) missing_files = [] archived_items = [] + missing_group = [] for p in persons: filename = p[0] + group_id = p[2] + if not group_id: + missing_group.append({ + "filename": filename, + "name": p[1] + }) + is_archived = bool(p[14]) if p[14] else False if is_archived: archived_items.append({ "filename": filename, - "group_id": p[2], + "group_id": group_id, "name": p[1] }) @@ -224,7 +232,7 @@ def _run_consistency_check(): if not os.path.exists(fpath): missing_files.append({ "filename": filename, - "group_id": p[2], + "group_id": group_id, "name": p[1] }) @@ -244,10 +252,11 @@ def _run_consistency_check(): "timestamp": time.time(), "missing_files": missing_files, "untracked_files": untracked_files, - "archived_items": archived_items + "archived_items": archived_items, + "missing_group": missing_group } _write_json(os.path.join(data_dir, "inconsistencies.json"), report) - print(f"[consistency] check complete: {len(missing_files)} missing, {len(untracked_files)} untracked, {len(archived_items)} archived") + print(f"[consistency] check complete: {len(missing_files)} missing, {len(untracked_files)} untracked, {len(archived_items)} archived, {len(missing_group)} missing group") return report except Exception as e: print(f"[consistency] check failed: {e}") @@ -1305,6 +1314,7 @@ def _write_all_static() -> None: "content_type": p[12] or "image", "faceswap_source_video": p[13], "archived": is_archived, + "is_source": bool(p[15]) if p[15] else False, }) print(f"[static] write_all: {len(db_images)} total images, {archived_count} archived") try: @@ -1674,8 +1684,9 @@ class GroupArchiveRequest(BaseModel): filenames: list[str] class RepairRequest(BaseModel): - action: str # "delete_record", "import_file", "restore", "delete_permanently" + action: str # "delete_record", "import_file", "restore", "delete_permanently", "assign_group" filename: str + group_id: str | None = None class BatchRequest(BaseModel): filenames: list[str] @@ -2377,10 +2388,17 @@ def db_repair(req: RepairRequest): if not os.path.exists(fpath): raise HTTPException(404, "File not found on disk") # Basic import: just register it in DB - database.upsert_person(req.filename, filepath=fpath, group_id=naming.get_base_name(req.filename)) + database.upsert_person(req.filename, filepath=fpath, group_id=naming.get_base_name(req.filename), is_source=True) _invalidate_static() _run_consistency_check() return {"status": "imported", "filename": req.filename} + elif req.action == "assign_group": + # Assign a group_id (default to base name if not provided) + gid = req.group_id or naming.get_base_name(req.filename) + database.upsert_person(req.filename, group_id=gid) + _invalidate_static() + _run_consistency_check() + return {"status": "assigned", "filename": req.filename, "group_id": gid} elif req.action == "restore": database.set_archived(req.filename, False) _invalidate_static() @@ -2516,6 +2534,7 @@ def _process_upload(file_path: str, filename: str, prompts: list[str], name: str filename, filepath=file_path, name=auto_name, clip_description=clip_desc, tags=tags, embedding=embedding, group_id=group_id, sort_order=0, has_clothing=has_clothing, + is_source=True, ) # Surface the new group with its base image right away — the pose/base-prompt # generation below can take a while, and the user shouldn't wait for it to @@ -2549,6 +2568,7 @@ def _process_upload(file_path: str, filename: str, prompts: list[str], name: str clip_description=clip_desc, embedding=out_embedding, group_id=group_id, sort_order=next_order, prompt=prompt, pose=out_pose, + source_refs=json.dumps([filename]), ) except Exception as e: print(f"Error processing prompt '{prompt}' for {filename}: {e}") @@ -2590,7 +2610,7 @@ def upload_image( if group_id and skip_poses: sort_order = database.get_next_sort_order(group_id) database.upsert_person(filename, filepath=file_path, group_id=group_id, - sort_order=sort_order) + sort_order=sort_order, is_source=True) _invalidate_static() return {"status": "added", "filename": filename, "group_id": group_id} @@ -2677,7 +2697,11 @@ def set_image_preferred(filename: str): raise HTTPException(404, "Image not found") group_id = person[1] if not group_id: - raise HTTPException(400, "Image has no group assigned") + # Auto-assign group_id if missing (legacy/orphan) + group_id = naming.get_base_name(filename) + database.upsert_person(filename, group_id=group_id) + print(f"[fix] Auto-assigned group_id={group_id} to orphan {filename} during set-preferred") + rows = database.get_group_order(group_id) others = [r[0] for r in rows if r[0] != filename] database.set_group_order(group_id, [filename] + others) @@ -3440,7 +3464,8 @@ def remove_background_sam(filename: str): # Register sidecar in DB so it appears in the same group group_id = person[1] database.upsert_person(nobg_filename, filepath=nobg_path, - group_id=group_id, has_background=False) + group_id=group_id, has_background=False, + source_refs=json.dumps([filename])) used_sam2 = _sam2_predictor is not False and _sam2_predictor is not None return { diff --git a/tour-comfy/embeddings.py b/tour-comfy/embeddings.py index e6551c3..b8a8bb4 100644 --- a/tour-comfy/embeddings.py +++ b/tour-comfy/embeddings.py @@ -2,29 +2,39 @@ import torch import open_clip from PIL import Image import os +import threading _model = None _preprocess = None _device = None +_lock = threading.Lock() def get_model(): global _model, _preprocess, _device if _model is None: - _device = "cuda" if torch.cuda.is_available() else "cpu" - # ViT-H-14 is 1024-dim - _model, _, _preprocess = open_clip.create_model_and_transforms('ViT-H-14', pretrained='laion2b_s32b_b79k') - _model = _model.to(_device) - _model.eval() + with _lock: + if _model is None: + dev = "cuda" if torch.cuda.is_available() else "cpu" + # ViT-H-14 is 1024-dim + model, _, preprocess = open_clip.create_model_and_transforms('ViT-H-14', pretrained='laion2b_s32b_b79k') + model = model.to(dev) + model.eval() + + # Set globals only when fully ready to avoid race conditions + _preprocess = preprocess + _device = dev + _model = model return _model, _preprocess, _device def generate_embedding(image_path): model, preprocess, device = get_model() try: - image = preprocess(Image.open(image_path)).unsqueeze(0).to(device) - with torch.no_grad(): - image_features = model.encode_image(image) - image_features /= image_features.norm(dim=-1, keepdim=True) - return image_features.cpu().numpy()[0].tolist() + with Image.open(image_path) as img: + image = preprocess(img.convert("RGB")).unsqueeze(0).to(device) + with torch.no_grad(): + image_features = model.encode_image(image) + image_features /= image_features.norm(dim=-1, keepdim=True) + return image_features.cpu().numpy()[0].tolist() except Exception as e: print(f"Error generating embedding for {image_path}: {e}") return None diff --git a/tour-comfy/poses.md b/tour-comfy/poses.md index 27a45ba..bd77bae 100644 --- a/tour-comfy/poses.md +++ b/tour-comfy/poses.md @@ -1,8 +1,17 @@ # Upscale HQ +Masterpiece. high quality. -detailed. -Anatomically precise, hyperrealistic, high detail, keep the characteristics of the reference image. +detailed. detailed skin. +Anatomically precise, photo realistic, high detail, keep the characteristics of the reference image. + +# Upscale HQ (18) + +Masterpiece. +high quality. +detailed. detailed skin. +teenage female. +Anatomically precise, photo realistic, high detail, keep the characteristics of the reference image. # BG Remove @@ -47,13 +56,18 @@ Keep full characteristics of reference image. # Three-quarter (18) You are in a black empty void. -high quality, masterpiece, detailed, detailed skin, Head-on a full-body three-quarter detailed full-nude-body, female teenage portrait, realistic, transparent background. +high quality, masterpiece, detailed, detailed skin. +Head-on a right-front detailed full-nude-body. Top-to-toe photo. +female teenage, photorealistic, sharp focus, transparent background. +Identical person from reference image. Keep characteristics of reference image. # Three-quarter You are in a black empty void. -high quality, masterpiece, detailed, detailed skin, Head-on a full-body three-quarter detailed full-nude-body, female portrait, realistic, transparent background. +high quality, masterpiece, detailed, detailed skin. +Head-on a right-front view. Top-to-toe. +detailed full-nude-body, female portrait, photorealistic, transparent background. Keep characteristics of reference image. # Head-on undress (18) @@ -71,13 +85,13 @@ Keep characteristics of reference image. # Head-on straight-on (18) You are in a black empty void. -Head-on straight-on full-body portrait, teenage female, realistic, black background. +Head-on straight-on full-body portrait, teenage female, photo realistic, black background. Keep characteristics of reference image. # Head-on straight-on You are in a black empty void. -Head-on straight-on full-body female portrait, realistic, black background. +Head-on straight-on full-body female portrait, photo realistic, black background. Keep characteristics of reference image. # Looking viewer (18) @@ -106,17 +120,26 @@ high quality, full-nude-body, female, masterpiece, realistic, photo, cinematic l transparent background. Keep characteristics of reference image. +# Merge (18)x3 + +masterpiece, you are in a black void, high quality, detailed, undress, combine the characteristics from reference images. +detailed skin, detailed full-nude-body. teenage female. +Photo-realistic. +Anatomically precise, keep the posture and gesture from the base image. + # Merge (18) masterpiece, you are in a black void, high quality, detailed, undress, combine the characteristics from reference images. detailed skin, detailed full-nude-body. teenage female. -hyper realistic. keep the posture and gesture from the base image. +hyper realistic. +Anatomically precise, keep the posture and gesture from the base image. # Merge masterpiece, you are in a black void, high quality, detailed, undress, combine the characteristics from reference images. detailed skin, detailed full-nude-body. female. -hyper realistic. keep the posture and gesture from the base image. +hyper realistic. +Anatomically precise, keep the posture and gesture from the base image. # Jewelery diff --git a/tour-comfy/trash.html b/tour-comfy/trash.html index 9e3c0f6..ca310e4 100644 --- a/tour-comfy/trash.html +++ b/tour-comfy/trash.html @@ -80,6 +80,11 @@
No archived items found.
+
+

Missing Group IDs (Legacy or orphaned images with no group assigned)

+
No images with missing groups found.
+
+

Orphaned Records (In DB, but file missing on disk)

No orphaned records found.
@@ -118,6 +123,7 @@ else if (d.status === 'imported') msg = 'File imported'; else if (d.status === 'restored') msg = 'Item restored'; else if (d.status === 'deleted_permanently') msg = 'Permanently deleted'; + else if (d.status === 'assigned') msg = 'Group assigned'; showToast(msg); loadInconsistencies(); @@ -137,6 +143,7 @@ renderArchived(d.archived_items || []); renderMissing(d.missing_files || []); renderUntracked(d.untracked_files || []); + renderOrphans(d.missing_group || []); if (d.timestamp) { const date = new Date(d.timestamp * 1000); @@ -150,6 +157,23 @@ } } + function renderOrphans(files) { + const container = document.getElementById('orphansList'); + if (files.length === 0) { + container.innerHTML = 'No images with missing groups found.'; + return; + } + container.innerHTML = files.map(f => ` +
+
+
${f.filename}
+
Name: ${f.name || 'none'}
+
+ +
+ `).join(''); + } + function renderArchived(files) { const container = document.getElementById('archivedList'); if (files.length === 0) { diff --git a/tour-comfy/watcher.py b/tour-comfy/watcher.py index a9041ea..bd5b241 100644 --- a/tour-comfy/watcher.py +++ b/tour-comfy/watcher.py @@ -189,7 +189,7 @@ def process_image(filename): try: embedding = embeddings.generate_embedding(output_path) gid = filename - database.upsert_person(output_filename, filepath=output_path, embedding=embedding, group_id=gid) + database.upsert_person(output_filename, filepath=output_path, embedding=embedding, group_id=gid, is_source=True) # Also trigger tagging to get auto-name and clip description tag_url = CONF["api_url"].replace("/edit", "/tag")