LLM + 图像处理的第一步:用自然语言驱动调色逻辑

一、起因:调色不该这么复杂

图像调色虽然看似只是微调一些滑块,实际上涉及多个关联参数:色温、亮度、对比度、饱和度、阴影、高光等等。对于普通用户来说,这些名词本身就不够直观,更别说理解它们之间的相互影响。即便是熟悉图像处理的用户,调出理想效果也往往需要多次尝试与回退。

我在开发图像编辑器 Monica(github.com/fengzhizi71...) 的过程中,一直希望降低调色门槛。于是,我开始尝试一个思路:能否用自然语言来驱动参数,让用户说一句话,比如"让肤色冷一点",系统就能自动完成一系列合理的参数调整?

随着近年来大模型(LLM)在语言理解和结构化输出方面的能力逐渐成熟,这个目标不再只是想象。我尝试接入一个 LLM 模型,为 Monica 增加一个「自然语言调色助手」。

二、我的方案:LLM + 参数结构

为了让大模型具备调色能力,我使用了 DeepSeek 提供的 API 接口。它支持中文自然语言输入,并且能够输出结构化 JSON 格式,便于程序直接解析使用。

用户每次输入一句自然语言指令,比如"肤色偏黄,冷一点",我会将当前的调色参数作为上下文信息,一起发送给模型。模型返回的结果是一组结构化的参数调整结果,例如:

json 复制代码
{
  "temperature": 200,
  "status": 5
}

其中各项参数值直接对应 Monica 的定义好的调色参数结构 ColorCorrectionSettings:

kotlin 复制代码
data class ColorCorrectionSettings(
    val contrast:Int = 255,     // 对比度,范围 0-510
    val hue:Int = 180,          // 色调,范围 0-360
    val saturation:Int = 255,   // 饱和度,范围 0-510
    val lightness:Int = 255,    // 亮度,范围 0-510
    val temperature:Int = 255,  // 色温,范围 0-510
    val highlight:Int = 255,    // 高光,范围 0-510
    val shadow:Int = 255,       // 阴影,范围 0-510
    val sharpen:Int = 0,        // 锐化,范围 0-255
    val corner:Int = 0,         // 暗角,范围 0-255

    val status:Int = 0 // 1 contrast, 2 hue, 3 saturation, 4 lightness, 5 temperature, 6 highlight, 7 shadow, 8 sharpen, 9 corner
)

所以每次调用后,模型会返回完整参数对象,我只需用返回的调色参数来更新图像效果。为了便于 UI 提示用户「这次改了什么」,ColorCorrectionSettings 恰好有一个辅助字段 status,用来标识当前轮被重点修改的参数,例如 status=5 表示"色温"发生了变化。

这套机制简单、稳定,并且可以自然支持"多轮会话",是后续构建交互式调色系统的基础。

三、关键实现点

3.1 Prompt 设计:构造有上下文的对话输入

为了让大模型理解并正确生成调色参数,我构造了一个包含当前参数上下文的 prompt。请求结构分为两部分:

  • system 消息:定义模型角色。例如:
swift 复制代码
"你是一个图像调色助手。用户会输入一句话,你需要将这句话转换为一组 JSON 格式的调色参数,字段说明如下:\\n\\n- contrast: 对比度,整数,范围 0 - 510,默认值 255。\\n- hue: 色调,整数,范围 0 - 360,默认值 180。\\n- saturation: 饱和度,整数,范围 0 - 510,默认值 255。\\n- lightness: 亮度,整数,范围 0 - 510,默认值 255。\\n- temperature: 色温,整数,范围 0 - 510,默认值 255。\\n- highlight: 高光,整数,范围 0 - 510,默认值 255。\\n- shadow: 阴影,整数,范围 0 - 510,默认值 255。\\n- sharpen: 锐化,整数,范围 0 - 255,默认值 0。\\n- corner: 暗角,整数,范围 0 - 255,默认值 0。\\n- status: 表示用户意图主要修改了哪一项(用于前端高亮显示),值如下:\\n  - 1 表示 contrast\\n  - 2 表示 hue\\n  - 3 表示 saturation\\n  - 4 表示 lightness\\n  - 5 表示 temperature\\n  - 6 表示 highlight\\n  - 7 表示 shadow\\n  - 8 表示 sharpen\\n  - 9 表示 corner\\n\\n要求:\\n- 不要输出解释。\\n- 严格输出 JSON 格式,字段顺序与上方一致。\\n- 如果用户输入不涉及某些参数,请保留默认值。\\n- 请根据语义合理推测用户意图。"
  • user 消息:拼接当前调色参数 + 用户输入的自然语言指令,格式如下:
makefile 复制代码
当前调色参数如下:
contrast: 255
hue: 180
...
用户指令:"让肤色冷一点"

这种组合方式可以让模型理解当前状态,并生成"增量式"的调整结果,避免从头生成。

3.2 多轮对话:基于当前参数持续调整

每次用户提交一句新指令,我会把上一次生成的参数作为"当前状态"传入下一轮请求中,实现连续调色。例如用户可以连续说:

  • "再亮一点"
  • "肤色更自然一点"
  • "暗角加重一些"

每轮模型输出的结果都会被解析为新的 ColorCorrectionSettings,并作为下一轮上下文继续参与交互。这种机制模拟了"连续对话中的状态记忆",用户无需重复说明所有内容。

我在客户端维护了一个 DialogSession 会话状态对象,这种方式避免了用户重复描述,也使模型具备了"记忆能力",调色过程更加连贯自然。

kotlin 复制代码
data class DialogSession(
    val systemPrompt: String,
    var currentSettings: ColorCorrectionSettings,
    val history: MutableList<Pair<String, ColorCorrectionSettings>> = mutableListOf()
)

3.3 Compose 弹窗组件:对话式调色界面

在 UI 层,我基于 Kotlin Compose 实现了一个轻量级的弹出对话框组件。主要功能包括:

  • 输入自然语言指令;
  • 调用 DeepSeek API 并异步等待响应;
  • 显示当前会话的历史记录(用户输入 + 模型响应);
  • 将参数更新实时传回图像处理模块,触发图像调整。

用户只需和"调色助手"对话,不再需要直接操作一堆滑块。

下面的代码展示了如何通过跟 DeepSeek 的 API 进行多轮对话,获取对应的调色参数,并把用户指令和调色参数保存。(省略了网络请求和解析 json 对象)

替换成其他的大模型也是类似的,比如换成 OpenAI 的 API 只要改少许代码即可。

kotlin 复制代码
/**
 * 每次根据当前参数和新指令拼 prompt, 支持多轮对话
 */
@Throws(MonicaException::class)
suspend fun applyInstructionWithLLM(
    session: DialogSession,
    instruction: String,
    apiKey: String
): ColorCorrectionSettings? {
    val prompt = buildString {
        append("当前图像的参数如下:\n")
        append(GsonUtils.toJson(session.currentSettings))
        append("\n\n")
        append("用户指令:$instruction")
    }
    val messages = mutableListOf<DeepSeekMessage>().apply {
        this.add(DeepSeekMessage(role = "system", content = systemPromptForColorCorrection))
        this.add(DeepSeekMessage(role = "user", content = prompt))
    }
    val deepSeekRequest = DeepSeekRequest("deepseek-chat", messages, false)
    val payload = GsonUtils.toJson(deepSeekRequest)

    val responseJson = sendPostJson(
        url = "https://api.deepseek.com/chat/completions",
        headers = mapOf("Content-Type" to "application/json",
            "Authorization" to "Bearer $apiKey"),
        body = payload
    )

    try {
        val json = extractJson(responseJson)
        val responseObj = GsonUtils.fromJson<ColorCorrectionSettings>(json, ColorCorrectionSettings::class.java)

        session.currentSettings = responseObj
        session.history.add(Pair(instruction, responseObj)) // 保存用户指令、调色参数
        return responseObj
    } catch (e: Exception) {
        logger.error("responseJson = $responseJson")
        logger.error(e.message, e)
        throw MonicaException("无法获取调色的参数")
    }
}

效果演示:

四、小结与展望

这次尝试只是一个起点,我用最简单的方式让 Monica 图像编辑器具备了自然语言调色的能力。借助大模型对中文语义的理解能力,用户无需理解"色温"、"对比度"等专业术语,只需要一句话就能驱动参数调整。

从技术实现上看,结构化参数 + prompt 工程 + 多轮上下文状态,是搭建语言驱动交互的关键几个要素。它也证明了传统图像处理工具完全可以与 LLM 接轨,提升交互体验,而不一定非要端到端"全自动"。

下一步,我可能会尝试接入更丰富的视觉模型,实现更多的功能,继续探索「自然语言 × 图像编辑」的边界。我也可能会考虑在本地部署 LLM,以提升响应速度和可控性。

图像编辑器 Monica 的地址:github.com/fengzhizi71...

相关推荐
白熊18834 分钟前
【大模型LLM】大模型训练加速 - 数据并行(Data Parallelism, DP)原理详解
人工智能·大模型·llm
青衫客3644 分钟前
LLM——使用 LangGraph 构建 ReAct 智能体:多轮对话 + 工具调用 + 可视化流程图
langchain·大模型·llm·agent·langgraph
kv18302 小时前
opencv解迷宫
人工智能·opencv·计算机视觉·广度优先搜索·图算法
AI大模型2 小时前
本地AI知识库问答开源技术实现(三)--配置模型和知识库
程序员·llm·agent
AI大模型2 小时前
大模型部署避坑指南:资源、速度与实战要点解析
程序员·llm·agent
bright_colo3 小时前
Python-初学openCV——图像预处理(六)
人工智能·opencv·计算机视觉
清朝牢弟4 小时前
Ubuntu系统VScode实现opencv(c++)图像放缩与插值
c++·vscode·opencv·ubuntu·计算机视觉
缘友一世5 小时前
Agents-SDK智能体开发[4]之集成MCP入门
llm·mcp·agents sdk
清朝牢弟7 小时前
Ubuntu系统VScode实现opencv(c++)视频的处理与保存
c++·人工智能·vscode·opencv·ubuntu