@@ -30,6 +30,7 @@ namespace fs = std::filesystem;
3030
3131const char * const modes_str[] = {
3232 " img_gen" ,
33+ " adetailer" ,
3334 " vid_gen" ,
3435 " convert" ,
3536 " upscale" ,
@@ -922,6 +923,26 @@ ArgOptions SDGenerationParams::get_options() {
922923 " the negative prompt (default: \"\" )" ,
923924 0 ,
924925 &negative_prompt},
926+ {" " ,
927+ " --ad-model" ,
928+ " path to a converted YOLOv8 detection model for ADetailer" ,
929+ 0 ,
930+ &ad_model_path},
931+ {" " ,
932+ " --ad-prompt" ,
933+ " ADetailer prompt; empty inherits the main prompt, supports [PROMPT], [SEP], and [SKIP]" ,
934+ 0 ,
935+ &ad_prompt},
936+ {" " ,
937+ " --ad-negative-prompt" ,
938+ " ADetailer negative prompt; empty inherits the main negative prompt, supports [PROMPT] and [SEP]" ,
939+ 0 ,
940+ &ad_negative_prompt},
941+ {" " ,
942+ " --extra-ad-args" ,
943+ " extra ADetailer args, key=value list. Supports input_size, confidence, nms, max_detections, mask_k_largest, mask_min_ratio, mask_max_ratio, dilate_erode, x_offset, y_offset, mask_mode, merge_masks, invert_mask, mask_blur, inpaint_padding, inpaint_width, inpaint_height, denoising_strength, steps, cfg_scale, sample_method, scheduler, sort_by" ,
944+ (int )' ,' ,
945+ &extra_ad_args},
925946 {" -i" ,
926947 " --init-img" ,
927948 " path to the init image" ,
@@ -1842,6 +1863,10 @@ bool SDGenerationParams::from_json_str(
18421863
18431864 load_if_exists (" prompt" , prompt);
18441865 load_if_exists (" negative_prompt" , negative_prompt);
1866+ load_if_exists (" ad_model" , ad_model_path);
1867+ load_if_exists (" ad_prompt" , ad_prompt);
1868+ load_if_exists (" ad_negative_prompt" , ad_negative_prompt);
1869+ load_if_exists (" extra_ad_args" , extra_ad_args);
18451870 load_if_exists (" cache_mode" , cache_mode);
18461871 load_if_exists (" cache_option" , cache_option);
18471872 load_if_exists (" scm_mask" , scm_mask);
@@ -2358,13 +2383,19 @@ bool SDGenerationParams::validate(SDMode mode) {
23582383 }
23592384 }
23602385
2361- if (mode == UPSCALE ) {
2386+ if (mode == UPSCALE || mode == ADETAILER ) {
23622387 if (init_image_path.length () == 0 ) {
2363- LOG_ERROR (" error: upscale mode needs an init image (--init-img)\n " );
2388+ LOG_ERROR (" error: %s mode needs an init image (--init-img)\n " ,
2389+ mode == UPSCALE ? " upscale" : " adetailer" );
23642390 return false ;
23652391 }
23662392 }
23672393
2394+ if (mode == ADETAILER && ad_model_path.empty ()) {
2395+ LOG_ERROR (" error: adetailer mode needs a detector model (--ad-model)\n " );
2396+ return false ;
2397+ }
2398+
23682399 return true ;
23692400}
23702401
@@ -2587,6 +2618,10 @@ std::string SDGenerationParams::to_string() const {
25872618 << " high_noise_loras: \" " << high_noise_loras_str << " \" ,\n "
25882619 << " prompt: \" " << prompt << " \" ,\n "
25892620 << " negative_prompt: \" " << negative_prompt << " \" ,\n "
2621+ << " ad_model_path: \" " << ad_model_path << " \" ,\n "
2622+ << " ad_prompt: \" " << ad_prompt << " \" ,\n "
2623+ << " ad_negative_prompt: \" " << ad_negative_prompt << " \" ,\n "
2624+ << " extra_ad_args: \" " << extra_ad_args << " \" ,\n "
25902625 << " clip_skip: " << clip_skip << " ,\n "
25912626 << " width: " << width << " ,\n "
25922627 << " height: " << height << " ,\n "
@@ -2701,8 +2736,13 @@ std::string build_sdcpp_image_metadata_json(const SDContextParams& ctx_params,
27012736 int64_t seed,
27022737 SDMode mode) {
27032738 json root;
2704- root[" schema" ] = " sdcpp.image.params/v1" ;
2705- root[" mode" ] = mode == VID_GEN ? " vid_gen" : " img_gen" ;
2739+ root[" schema" ] = " sdcpp.image.params/v1" ;
2740+ root[" mode" ] = " img_gen" ;
2741+ if (mode == VID_GEN ) {
2742+ root[" mode" ] = " vid_gen" ;
2743+ } else if (mode == ADETAILER ) {
2744+ root[" mode" ] = " adetailer" ;
2745+ }
27062746 root[" generator" ] = {
27072747 {" name" , " stable-diffusion.cpp" },
27082748 {" version" , safe_json_string (sd_version ())},
@@ -2716,6 +2756,14 @@ std::string build_sdcpp_image_metadata_json(const SDContextParams& ctx_params,
27162756 {" positive" , gen_params.prompt },
27172757 {" negative" , gen_params.negative_prompt },
27182758 };
2759+ if (!gen_params.ad_model_path .empty ()) {
2760+ root[" adetailer" ] = {
2761+ {" model" , sd_basename (gen_params.ad_model_path )},
2762+ {" prompt" , gen_params.ad_prompt },
2763+ {" negative_prompt" , gen_params.ad_negative_prompt },
2764+ {" extra_args" , gen_params.extra_ad_args },
2765+ };
2766+ }
27192767 root[" sampling" ] = build_sampling_metadata_json (gen_params.sample_params ,
27202768 gen_params.skip_layers ,
27212769 &gen_params.custom_sigmas );
@@ -2870,6 +2918,18 @@ std::string get_image_params(const SDContextParams& ctx_params,
28702918 if (!gen_params.extra_sample_args .empty ()) {
28712919 parameter_string += " Extra sample args: " + gen_params.extra_sample_args + " , " ;
28722920 }
2921+ if (!gen_params.ad_model_path .empty ()) {
2922+ parameter_string += " ADetailer model: " + sd_basename (gen_params.ad_model_path ) + " , " ;
2923+ if (!gen_params.ad_prompt .empty ()) {
2924+ parameter_string += " ADetailer prompt: " + gen_params.ad_prompt + " , " ;
2925+ }
2926+ if (!gen_params.ad_negative_prompt .empty ()) {
2927+ parameter_string += " ADetailer negative prompt: " + gen_params.ad_negative_prompt + " , " ;
2928+ }
2929+ if (!gen_params.extra_ad_args .empty ()) {
2930+ parameter_string += " ADetailer args: " + gen_params.extra_ad_args + " , " ;
2931+ }
2932+ }
28732933 parameter_string += " Seed: " + std::to_string (seed) + " , " ;
28742934 parameter_string += " Size: " + std::to_string (gen_params.get_resolved_width ()) + " x" + std::to_string (gen_params.get_resolved_height ()) + " , " ;
28752935 parameter_string += " Model: " + sd_basename (ctx_params.model_path ) + " , " ;
0 commit comments