Skip to content

Commit

Permalink
feat: add Tile Image Processor to Linear UI
Browse files Browse the repository at this point in the history
  • Loading branch information
blessedcoolant committed Jun 29, 2024
1 parent 182e2fd commit 3dc5566
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 123 deletions.
2 changes: 1 addition & 1 deletion invokeai/app/invocations/controlnet_image_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ def tile_resample(self, np_img: np.ndarray[Any, Any]):
)
np_img = cv2.resize(np_img, (resize_w, resize_h), interpolation=cv2.INTER_CUBIC)

np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
# np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)

return np_img

Expand Down
9 changes: 6 additions & 3 deletions invokeai/backend/model_manager/probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,11 @@ def _get_checkpoint_config_path(
config_file = (
"stable-diffusion/v1-inference.yaml"
if base_type is BaseModelType.StableDiffusion1
else "stable-diffusion/sd_xl_base.yaml"
if base_type is BaseModelType.StableDiffusionXL
else "stable-diffusion/v2-inference.yaml"
else (
"stable-diffusion/sd_xl_base.yaml"
if base_type is BaseModelType.StableDiffusionXL
else "stable-diffusion/v2-inference.yaml"
)
)
else:
raise InvalidModelConfigException(
Expand Down Expand Up @@ -361,6 +363,7 @@ def _scan_model(cls, model_name: str, checkpoint: Path) -> None:
"pose": "dw_openpose_image_processor",
"mediapipe": "mediapipe_face_processor",
"pidi": "pidi_image_processor",
"tile": "tile_image_processor",
"zoe": "zoe_depth_image_processor",
"color": "color_map_image_processor",
}
Expand Down
8 changes: 8 additions & 0 deletions invokeai/frontend/web/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@
"dwOpenposeDescription": "Human pose estimation using DW Openpose",
"pidi": "PIDI",
"pidiDescription": "PIDI image processing",
"tile": "Tile",
"TileDescription": "Tile Resampling",
"mode": "Mode",
"downsamplingRate": "Downsampling Rate",
"regular": "Regular",
"blur": "Blur",
"variation": "Variation",
"super": "Super",
"processor": "Processor",
"prompt": "Prompt",
"resetControlImage": "Reset Control Image",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,21 @@ export const CONTROLNET_PROCESSORS: ControlNetProcessorsDict = {
safe: false,
}),
},
tile_image_processor: {
type: 'tile_image_processor',
get label() {
return i18n.t('controlnet.tile');
},
get description() {
return i18n.t('controlnet.tileDescription');
},
buildDefaults: () => ({
id: 'tile_image_processor',
type: 'tile_image_processor',
down_sampling_rate: 1.0,
mode: 'blur',
}),
},
zoe_depth_image_processor: {
type: 'zoe_depth_image_processor',
get label() {
Expand Down
15 changes: 15 additions & 0 deletions invokeai/frontend/web/src/features/controlAdapters/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type ControlAdapterProcessorNode =
| Invocation<'normalbae_image_processor'>
| Invocation<'dw_openpose_image_processor'>
| Invocation<'pidi_image_processor'>
| Invocation<'tile_image_processor'>
| Invocation<'zoe_depth_image_processor'>;

/**
Expand All @@ -46,6 +47,7 @@ export const zControlAdapterProcessorType = z.enum([
'normalbae_image_processor',
'dw_openpose_image_processor',
'pidi_image_processor',
'tile_image_processor',
'zoe_depth_image_processor',
'none',
]);
Expand Down Expand Up @@ -161,6 +163,14 @@ export type RequiredPidiImageProcessorInvocation = O.Required<
'type' | 'detect_resolution' | 'image_resolution' | 'safe' | 'scribble'
>;

/**
* The Tile processor node, with parameters flagged as required
*/
export type RequiredTileImageProcessorInvocation = O.Required<
Invocation<'tile_image_processor'>,
'type' | 'down_sampling_rate' | 'mode'
>;

/**
* The ZoeDepth processor node, with parameters flagged as required
*/
Expand All @@ -184,6 +194,7 @@ export type RequiredControlAdapterProcessorNode =
| RequiredNormalbaeImageProcessorInvocation
| RequiredDWOpenposeImageProcessorInvocation
| RequiredPidiImageProcessorInvocation
| RequiredTileImageProcessorInvocation
| RequiredZoeDepthImageProcessorInvocation,
'id'
>
Expand All @@ -199,6 +210,10 @@ const zIPMethod = z.enum(['full', 'style', 'composition']);
export type IPMethod = z.infer<typeof zIPMethod>;
export const isIPMethod = (v: unknown): v is IPMethod => zIPMethod.safeParse(v).success;

const zTileProcessorMode = z.enum(['regular', 'blur', 'var', 'super']);
export type TileProcessorMode = z.infer<typeof zTileProcessorMode>;
export const isTileProcessorMode = (v: unknown): v is TileProcessorMode => zTileProcessorMode.safeParse(v).success;

export type ControlNetConfig = {
type: 'controlnet';
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MediapipeFaceProcessor } from './processors/MediapipeFaceProcessor';
import { MidasDepthProcessor } from './processors/MidasDepthProcessor';
import { MlsdImageProcessor } from './processors/MlsdImageProcessor';
import { PidiProcessor } from './processors/PidiProcessor';
import { TileProcessor } from './processors/TileProcessor';

type Props = {
config: ProcessorConfig | null;
Expand Down Expand Up @@ -77,6 +78,10 @@ export const ControlAdapterProcessorConfig = memo(({ config, onChange }: Props)
return <PidiProcessor onChange={onChange} config={config} />;
}

if (config.type === 'tile_image_processor') {
return <TileProcessor onChange={onChange} config={config} />;
}

if (config.type === 'zoe_depth_image_processor') {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
import { Combobox, CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { isTileProcessorMode, type TileProcessorMode } from 'features/controlAdapters/store/types';
import type { ProcessorComponentProps } from 'features/controlLayers/components/ControlAndIPAdapter/processors/types';
import { CA_PROCESSOR_DATA, type TileProcessorConfig } from 'features/controlLayers/util/controlAdapters';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import ProcessorWrapper from './ProcessorWrapper';

type Props = ProcessorComponentProps<TileProcessorConfig>;
const DEFAULTS = CA_PROCESSOR_DATA['tile_image_processor'].buildDefaults();

export const TileProcessor = memo(({ onChange, config }: Props) => {
const { t } = useTranslation();

const tileModeOptions: { label: string; value: TileProcessorMode }[] = useMemo(
() => [
{ label: t('controlnet.regular'), value: 'regular' },
{ label: t('controlnet.blur'), value: 'blur' },
{ label: t('controlnet.variation'), value: 'var' },
{ label: t('controlnet.super'), value: 'super' },
],
[t]
);

const tileModeValue = useMemo(() => tileModeOptions.find((o) => o.value === config.mode), [tileModeOptions, config]);

const handleTileModeChange = useCallback<ComboboxOnChange>(
(v) => {
if (!isTileProcessorMode(v?.value)) {
return;
}
onChange({ ...config, mode: v.value });
},
[config, onChange]
);

const handleDownSamplingRateChanged = useCallback(
(v: number) => {
onChange({ ...config, down_sampling_rate: v });
},
[config, onChange]
);

return (
<ProcessorWrapper>
<FormControl>
<FormLabel m={0}>{t('controlnet.mode')}</FormLabel>
<Combobox value={tileModeValue} options={tileModeOptions} onChange={handleTileModeChange} />
</FormControl>
<FormControl>
<FormLabel m={0}>{t('controlnet.downsamplingRate')}</FormLabel>
<CompositeSlider
value={config.down_sampling_rate}
onChange={handleDownSamplingRateChanged}
defaultValue={DEFAULTS.down_sampling_rate}
min={0}
max={5}
step={0.1}
marks
/>
<CompositeNumberInput
value={config.down_sampling_rate}
onChange={handleDownSamplingRateChanged}
defaultValue={DEFAULTS.down_sampling_rate}
min={0}
max={5}
step={0.1}
/>
</FormControl>
</ProcessorWrapper>
);
});

TileProcessor.displayName = 'TileProcessor';
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
PidiProcessorConfig,
ProcessorConfig,
ProcessorTypeV2,
TileProcessorConfig,
ZoeDepthProcessorConfig,
} from './controlAdapters';

Expand Down Expand Up @@ -58,6 +59,7 @@ describe('Control Adapter Types', () => {
assert<Equals<_NormalbaeProcessorConfig, NormalbaeProcessorConfig>>();
assert<Equals<_DWOpenposeProcessorConfig, DWOpenposeProcessorConfig>>();
assert<Equals<_PidiProcessorConfig, PidiProcessorConfig>>();
assert<Equals<_TileProcessorConfig, TileProcessorConfig>>();
assert<Equals<_ZoeDepthProcessorConfig, ZoeDepthProcessorConfig>>();
});
});
Expand Down Expand Up @@ -90,4 +92,7 @@ type _DWOpenposeProcessorConfig = Required<
Pick<Invocation<'dw_openpose_image_processor'>, 'id' | 'type' | 'draw_body' | 'draw_face' | 'draw_hands'>
>;
type _PidiProcessorConfig = Required<Pick<Invocation<'pidi_image_processor'>, 'id' | 'type' | 'safe' | 'scribble'>>;
type _TileProcessorConfig = Required<
Pick<Invocation<'tile_image_processor'>, 'id' | 'type' | 'down_sampling_rate' | 'mode'>
>;
type _ZoeDepthProcessorConfig = Required<Pick<Invocation<'zoe_depth_image_processor'>, 'id' | 'type'>>;
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ const zPidiProcessorConfig = z.object({
});
export type PidiProcessorConfig = z.infer<typeof zPidiProcessorConfig>;

const zTileProcessorConfig = z.object({
id: zId,
type: z.literal('tile_image_processor'),
down_sampling_rate: z.number().gte(0),
mode: z.enum(['regular', 'blur', 'var', 'super']),
});
export type TileProcessorConfig = z.infer<typeof zTileProcessorConfig>;

const zZoeDepthProcessorConfig = z.object({
id: zId,
type: z.literal('zoe_depth_image_processor'),
Expand All @@ -134,6 +142,7 @@ const zProcessorConfig = z.discriminatedUnion('type', [
zNormalbaeProcessorConfig,
zDWOpenposeProcessorConfig,
zPidiProcessorConfig,
zTileProcessorConfig,
zZoeDepthProcessorConfig,
]);
export type ProcessorConfig = z.infer<typeof zProcessorConfig>;
Expand Down Expand Up @@ -212,6 +221,7 @@ const zProcessorTypeV2 = z.enum([
'normalbae_image_processor',
'dw_openpose_image_processor',
'pidi_image_processor',
'tile_image_processor',
'zoe_depth_image_processor',
]);
export type ProcessorTypeV2 = z.infer<typeof zProcessorTypeV2>;
Expand Down Expand Up @@ -453,6 +463,22 @@ export const CA_PROCESSOR_DATA: CAProcessorsData = {
image_resolution: minDim(image),
}),
},
tile_image_processor: {
type: 'tile_image_processor',
labelTKey: 'controlnet.tile',
descriptionTKey: 'controlnet.tileDescription',
buildDefaults: () => ({
id: 'tile_image_processor',
type: 'tile_image_processor',
down_sampling_rate: 1.0,
mode: 'regular',
}),
buildNode: (image, config) => ({
...config,
type: 'tile_image_processor',
image: { image_name: image.name },
}),
},
zoe_depth_image_processor: {
type: 'zoe_depth_image_processor',
labelTKey: 'controlnet.depthZoe',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const OPTIONS = [
{ label: 'Depth Anything', value: 'depth_anything_image_processor' },
{ label: 'Normal BAE', value: 'normalbae_image_processor' },
{ label: 'Pidi', value: 'pidi_image_processor' },
{ label: 'Tile', value: 'tile_image_processor' },
{ label: 'Lineart', value: 'lineart_image_processor' },
{ label: 'Lineart Anime', value: 'lineart_anime_image_processor' },
{ label: 'HED', value: 'hed_image_processor' },
Expand Down
Loading

0 comments on commit 3dc5566

Please sign in to comment.