defmodule Evision.Zoo.TextRecognition.CRNN do @moduledoc """ An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition. 'FP16' or 'INT8' stands for 'model quantized into FP16' or 'model quantized into int8'. - `CRNN_EN` and it variants can detect digits (0-9) and letters (return lowercase letters a-z). - `CRNN_CH` and it variants can detect digits (0-9), upper/lower-case letters (a-z and A-Z), and some special characters. - `CRNN_CN` and it variants can detect digits (0-9), upper/lower-case letters (a-z and A-Z), some Chinese characters and some special characters. """ @doc """ Default configuration. """ @spec default_config :: map() def default_config do %{ backend: Evision.Constant.cv_DNN_BACKEND_OPENCV(), target: Evision.Constant.cv_DNN_TARGET_CPU(), detector: "db_ic15_resnet18" } end @doc """ Customizable parameters from smart cell. """ @spec smartcell_params() :: Evision.Zoo.smartcell_params() def smartcell_params() do config = default_config() [ %{ name: "Recognizer", params: [ %{field: "detector", label: "Text Detector", type: :string, default: config[:detector], is_option: true, options: [ %{value: "db_ic15_resnet18", label: "DB IC15 ResNet18"}, %{value: "db_ic15_resnet50", label: "DB IC15 ResNet50"}, %{value: "db_td500_resnet18", label: "DB TD500 ResNet18"}, %{value: "db_td500_resnet50", label: "DB TD500 ResNet50"}, %{value: "ppocrv3_en", label: "PP-OCR V3 EN"}, %{value: "ppocrv3_en_int8", label: "PP-OCR V3 EN (int8)"}, %{value: "ppocrv3_cn", label: "PP-OCR V3 CN"}, %{value: "ppocrv3_cn_int8", label: "PP-OCR V3 CN (int8)"}, ] }, ] } ] ++ Evision.Zoo.TextDetection.DB.smartcell_params() end @doc """ Initialize model. ##### Positional arguments - **model**: `String.t()` | `:en` | `:en_fp16` | `:en_int8` | `:ch` | `:ch_fp16` | `:ch_int8` | `:cn` | `:cn_int8`. - When `model` is a string, it will be treat as the path to a weight file and `init/2` will load the model from it. - When `model` is one the allowed atoms, `init/2` will download and load the predefined model. ##### Keyword arguments - **cache_dir**: `String.t()`. Path to the cache directory. Optional. Defaults to `:filename.basedir(:user_cache, "", ...)` - **backend**: `integer()`. Specify the backend. Optional. Defaults to `Evision.Constant.cv_DNN_BACKEND_OPENCV()`. - **target**: `integer()`. Specify the target. Optional. Defaults to `Evision.Constant.cv_DNN_TARGET_CPU()`. """ @spec init(binary | :en | :en_fp16 | :en_int8 | :ch | :ch_fp16 | :ch_int8 | :cn | :cn_int8, nil | Keyword.t()) :: {:error, String.t()} | Evision.DNN.Net.t() def init(model_path, opts \\ []) def init(model_type, opts) when model_type in [:en, :en_fp16, :en_int8, :ch, :ch_fp16, :ch_int8, :cn, :cn_int8] do {model_url, filename} = model_info(model_type) cache_dir = opts[:cache_dir] with {:ok, local_path} <- Evision.Zoo.download(model_url, filename, cache_dir: cache_dir) do init(local_path, opts) else {:error, msg} -> raise msg end end def init(model_path, opts) when is_binary(model_path) do config = default_config() backend = opts[:backend] || config[:backend] target = opts[:target] || config[:target] model = Evision.DNN.readNet(model_path) Evision.DNN.Net.setPreferableBackend(model, backend) Evision.DNN.Net.setPreferableTarget(model, target) model end @doc """ Inference. ##### Positional arguments - **self**: `Evision.DNN.Net.t()`. An initialized CRNN model. - **image**: `Evision.Mat.maybe_mat_in()`. Input image. - **rotation_box**: `Evision.Mat.maybe_mat_in()`. Rotation box. ##### Keyword arguments - **charset**: `[binary]` | `:en` | `:ch` | `:cn` Required. The corresponding charset for the model. - **to_gray**: `boolean`. Required. The input image need to be converted to grayscale if the model is `:en*`. Please set to `true` if the model is `:en*`. """ @spec infer(Evision.DNN.Net.t(), Evision.Mat.maybe_mat_in(), Evision.Mat.maybe_mat_in(), Keyword.t()) :: String.t() def infer(self=%Evision.DNN.Net{}, image, rotation_box, opts \\ []) do # Preprocess to_gray = opts[:to_gray] || false inputBlob = preprocess(image, rotation_box, to_gray) # Forward Evision.DNN.Net.setInput(self, inputBlob) outputBlob = Evision.DNN.Net.forward(self, outputName: "") outputBlob = if is_list(outputBlob) do [outputBlob] = outputBlob outputBlob else outputBlob end # Postprocess charset = opts[:charset] postprocess(outputBlob, charset) end @doc """ Preprocessing the input image. `infer/4` will call this function automatically. ##### Positional arguments - **image**: `Evision.Mat.maybe_mat_in()`. Input image. """ @spec preprocess(Evision.Mat.maybe_mat_in(), Evision.Mat.maybe_mat_in(), boolean()) :: Evision.Mat.t() def preprocess(image, rotation_box, to_gray) do vertices = Evision.Mat.as_type(Evision.Mat.as_type(Evision.boxPoints(rotation_box), :s32), :f32) rotationMatrix = Evision.getPerspectiveTransform(vertices, target_vertices()) cropped = Evision.warpPerspective(image, rotationMatrix, input_size()) input = if to_gray do Evision.cvtColor(cropped, Evision.Constant.cv_COLOR_RGB2GRAY()) else cropped end Evision.DNN.blobFromImage(input, size: input_size(), mean: 127.5, scalefactor: 1.0/127.5) end @doc """ Postprocessing the results. `infer/4` will call this function automatically. ##### Positional arguments - **image**: `Evision.Mat.maybe_mat_in()`. Input image. """ @spec postprocess(Evision.Mat.t(), :ch | :cn | :en | list(String.t())) :: String.t() def postprocess(outputBlob=%Evision.Mat{}, charset) do output = Evision.Mat.to_nx(outputBlob, Nx.BinaryBackend) charset = case charset do charset when charset in [:ch, :cn, :en] -> get_charset(charset) charset when is_list(charset) -> charset _ -> raise "Invalid charset: #{inspect(charset)}" end num_chars = elem(outputBlob.shape, 0) chars = for i <- 0..num_chars-1, into: [] do c = Nx.to_number(Nx.argmax(output[[i, 0]])) case c do 0 -> "-" _ -> Enum.at(charset, c - 1) end end case chars do [] -> "" _ -> for i <- 0..Enum.count(chars)-1, into: <<>> do c = Enum.at(chars, i) case c do "-" -> "" _ -> if not(i > 0 and Enum.at(chars, i + 1, "-") == c) do c else "" end end end end end def postprocess(_, _) do "" end @doc """ Model URL and filename of predefined model. """ @spec model_info(:ch | :ch_fp16 | :ch_int8 | :cn | :cn_int8 | :en | :en_fp16 | :en_int8) :: {String.t(), String.t()} def model_info(:en) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_EN_2021sep.onnx", "text_recognition_CRNN_EN_2021sep.onnx" } end def model_info(:en_fp16) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_EN_2023feb_fp16.onnx", "text_recognition_CRNN_EN_2023feb_fp16.onnx" } end def model_info(:en_int8) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_EN_2022oct_int8.onnx", "text_recognition_CRNN_EN_2022oct_int8.onnx" } end def model_info(:ch) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_CH_2021sep.onnx", "text_recognition_CRNN_CH_2021sep.onnx" } end def model_info(:ch_fp16) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_CH_2023feb_fp16.onnx", "text_recognition_CRNN_CH_2023feb_fp16.onnx" } end def model_info(:ch_int8) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_CH_2022oct_int8.onnx", "text_recognition_CRNN_CH_2022oct_int8.onnx" } end def model_info(:cn) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_CN_2021nov.onnx", "text_recognition_CRNN_CN_2021nov.onnx" } end def model_info(:cn_int8) do { "https://github.com/opencv/opencv_zoo/raw/fd2da740ebc6d0fe489d86cb55133148978cd82e/models/text_recognition_crnn/text_recognition_CRNN_CN_2021nov_int8.onnx", "text_recognition_CRNN_CN_2021nov_int8.onnx" } end def charset_info(en) when en in [:en, :en_fp16, :en_int8] do charset_36_EN() end def charset_info(ch) when ch in [:ch, :ch_fp16, :ch_int8] do charset_94_CH() end def charset_info(cn) when cn in [:cn, :cn_int8] do charset_3944_CN() end def chartset_info(other) do raise """ Cannot find predefined charset `#{inspect(other)}`. However, you can load the charset that corresponds to your model and pass it when calling `infer/`. The custom charset should be a list of characters. For example: charset = String.split(File.read!("my-charset.txt"), "\n") Evision.Zoo.TextRecognition.CRNN.infer(recognizer, image, Enum.at(detections, 0), charset: charset, to_gray: lang == "en") """ end @doc """ Get default input size """ @spec input_size :: {100, 32} def input_size do {100, 32} end @doc """ Get default target vertices """ @spec target_vertices :: Nx.Tensor.t() def target_vertices do {input_width, input_height} = input_size() Nx.tensor( [ [0, input_height - 1], [0, 0], [input_width - 1, 0], [input_width - 1, input_height - 1] ], type: :f32, backend: Nx.BinaryBackend ) end @doc """ Get charset """ @spec get_charset(:ch | :cn | :en) :: [binary] def get_charset(model_type) do String.split(charset_info(model_type), "\n") end @doc """ Visualize the result. ##### Positional arguments - **image**: `Evision.Mat.maybe_mat_in()`. Original image. - **results**: `Evision.Mat.maybe_mat_in()`. Results given by `infer/2`. ##### Keyword arguments - **box_color**: `{blue=integer(), green=integer(), red=integer()}`. Values should be in `[0, 255]`. Defaults to `{0, 255, 0}`. Specify the color of the bounding box. - **text_color**: `{blue=integer(), green=integer(), red=integer()}`. Values should be in `[0, 255]`. Defaults to `{0, 0, 255}`. Specify the color of the text (confidence value). """ def visualize(image, texts, detections, confidences, opts \\ []) do box_color = opts[:box_color] || {0, 255, 0} text_color = opts[:text_color] || {0, 0, 255} Enum.reduce(Enum.zip([texts, detections, confidences]), image, fn {text, pts, conf}, img -> [b0, b1 | _] = Nx.to_flat_list(pts) conf = Float.round(conf, 2) Evision.polylines(img, [pts], true, box_color, thickness: 2) |> Evision.putText("#{conf}: #{text}", {b0, b1 + 12}, Evision.Constant.cv_FONT_HERSHEY_DUPLEX(), 1.0, text_color) end) end @doc """ Docs in smart cell. """ @spec docs() :: String.t() def docs do @moduledoc end @doc """ Smart cell tasks. A list of variants of the current model. """ @spec smartcell_tasks() :: Evision.Zoo.smartcell_tasks() def smartcell_tasks do [ %{ id: "crnn_en", label: "CRNN EN", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_en_fp16", label: "CRNN EN (FP16)", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_en_int8", label: "CRNN EN (INT8)", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_ch", label: "CRNN CH", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_ch_fp16", label: "CRNN CH (FP16)", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_ch_int8", label: "CRNN CH (INT8)", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_cn", label: "CRNN CN", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, %{ id: "crnn_cn_int8", label: "CRNN CN (INT8)", docs_url: "https://github.com/opencv/opencv_zoo/tree/master/models/text_recognition_crnn", params: smartcell_params(), docs: docs() }, ] end @doc """ Generate quoted code from smart cell attrs. """ @spec to_quoted(map()) :: list() def to_quoted(attrs) do {backend, target} = Evision.Zoo.to_quoted_backend_and_target(attrs) opts = [ backend: backend, target: target ] {detector_width, detector_height} = {attrs["width"], attrs["height"]} {model, to_gray?, charset} = case attrs["variant_id"] do "crnn_" <> variant_id -> case variant_id do "en" <> _ -> {String.to_atom(variant_id), true, :en} "ch" <> _ -> {String.to_atom(variant_id), false, :ch} "cn" <> _ -> {String.to_atom(variant_id), false, :cn} _ -> raise "Unknown variant: crnn_#{inspect(variant_id)}" end unknown_id -> raise "Unknown variant: #{inspect(unknown_id)}" end {detector_module, detector_model} = case attrs["detector"] do "db_" <> db_detector -> case db_detector do db_detector when db_detector in ["ic15_resnet18", "ic15_resnet50", "td500_resnet18", "td500_resnet50"] -> {Evision.Zoo.TextDetection.DB, String.to_atom(db_detector)} _ -> raise "Unknown DB variant: #{inspect(db_detector)}" end "ppocrv3_" <> ppocrv3_detector -> case ppocrv3_detector do ppocrv3_detector when ppocrv3_detector in ["en", "en_int8", "cn", "cn_int8"] -> {Evision.Zoo.TextDetection.PPOCRV3, String.to_atom(ppocrv3_detector)} _ -> raise "Unknown PP-OCR V3 variant: #{inspect(ppocrv3_detector)}" end unknown_id -> raise "Unknown text detector: #{inspect(unknown_id)}" end [ quote do detector = unquote(detector_module).init(unquote(detector_model), unquote(opts)) recognizer = Evision.Zoo.TextRecognition.CRNN.init(unquote(model), unquote(opts)) end, quote do image_input = Kino.Input.image("Image") form = Kino.Control.form([image: image_input], submit: "Run") frame = Kino.Frame.new() form |> Kino.Control.stream() |> Stream.filter(& &1.data.image) |> Kino.listen(fn %{data: %{image: image}} -> Kino.Frame.render(frame, Kino.Markdown.new("Running...")) {original_height, original_width} = {image.height, image.width} scale_height = original_height / unquote(detector_height) scale_width = original_width / unquote(detector_width) image = image.file_ref |> Kino.Input.file_path() |> File.read!() |> Evision.Mat.from_binary({:u, 8}, image.height, image.width, 3) image_ = Evision.resize(image, unquote({detector_width, detector_height})) charset = Evision.Zoo.TextRecognition.CRNN.get_charset(unquote(charset)) {detections, confidences} = unquote(detector_module).infer(detector, image_) texts = Enum.map(detections, &Evision.Zoo.TextRecognition.CRNN.infer( recognizer, image_, &1, to_gray: unquote(to_gray?), charset: charset)) detections = Enum.map(detections, fn d -> Nx.multiply( Evision.Mat.to_nx(Evision.boxPoints(d), Nx.BinaryBackend), Nx.tensor([scale_width, scale_height], backend: Nx.BinaryBackend) ) |> Nx.as_type(:s32) end) image = Evision.cvtColor(image, Evision.Constant.cv_COLOR_RGB2BGR()) vis_img = Evision.Zoo.TextRecognition.CRNN.visualize(image, texts, detections, confidences) Kino.Frame.render(frame, Kino.Image.new(Evision.imencode(".png", vis_img), :png)) end) Kino.Layout.grid([form, frame], boxed: true, gap: 16) end ] end @doc """ Charset that contains digits (0~9) and letters (return lowercase letters a~z). Content copied from `charset_36_EN.txt`. """ def charset_36_EN do """ 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z """ end @doc """ Charset that contains digits (0~9), upper/lower-case letters (a~z and A~Z), and some special characters. Content copied from `charset_94_CH.txt`. """ def charset_94_CH do """ 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ """ end @doc """ Charset that contains digits (0~9), upper/lower-case letters (a~z and A~Z), some Chinese characters and some special characters. Content copied from `charset_94_CH.txt`. """ def charset_3944_CN do """ H O K I T E A 酱 鸭 传 奇 J N G Y C U Q 蝦 兵 蟹 煲 这 是 可 以 先 吃 后 涮 的 干 锅 菜 加 盟 电 话 : 1 7 3 9 8 郑 州 总 店 雪 花 勇 闯 天 涯 虾 , 一 送 鱼 锡 纸 蛤 土 豆 粉 砂 米 线 牛 筋 面 刀 削 水 饺 吧 沙 拉 老 饭 盒 教 室 主 题 餐 厅 仁 馄 饨 重 庆 小 便 当 全 国 连 锁 4 0 - 6 5 2 人 快 量 贩 蓬 朗 御 茶 川 渝 捞 火 古 之 匠 今 七 西 域 羊 城 l i k n g c o f e w 贵 阳 素 有 家 会 展 口 乐 三 惹 烤 肉 h t 子 馆 常 盖 浇 兴 业 路 书 亦 燒 仙 草 L : 德 啤 工 坊 杏 屋 高 桥 号 品 麻 辣 烫 检 官 . 千 翼 木 兰 画 食 上 汤 剁 馅 手 煮 时 尚 健 康 傲 椒 B 啵 条 脾 气 ! / 月 腾 讯 应 用 喵 泡 我 鲜 滚 给 你 看 客 来 香 汉 湘 本 地 炒 系 列 订 仔 肘 蹄 梅 扣 黄 焖 排 骨 炖 鸡 韓 金 利 串 舊 街 梨 村 座 经 济 实 惠 绿 色 炭 庐 蛙 忆 蓉 源 真 d D 概 念 创 意 六 熏 各 种 精 美 y 疯 狂 世 界 杯 特 价 酒 元 瓶 沸 带 F 请 二 楼 自 动 升 降 烏 邦 嗦 味 风 货 团 外 卖 嘞 个 折 辛 束 舌 尖 中 包 浆 腐 r P a u 丸 作 福 M 漫 蜜 冰 拌 匆 那 年 R S 果 光 夹 馍 凉 皮 过 祖 南 山 風 景 堂 烘 培 龍 坎 半 婆 建 设 富 强 丽 菏 泽 省 安 港 竹 签 撩 只 为 好 生 活 抓 海 最 网 红 铁 统 ® 功 夫 鱿 大 闻 就 知 遇 见 文 合 热 森 台 湾 卤 然 汁 甄 选 材 还 原 初 衷 * 洪 龙 公 酸 巴 乡 焦 烧 淘 成 都 眼 镜 优 菓 恋 V 化 糖 、 粥 田 螺 斓 X 爺 W j 院 华 Z 蜊 北 京 刷 蝎 腿 梦 幻 奶 式 蛋 鍋 区 · 领 航 者 四 通 往 楚 河 停 车 场 凌 晨 点 杞 缘 王 集 唐 菠 萝 泰 板 鳳 凰 樓 名 壹 猪 晴 舍 犟 师 傅 飯 致 青 春 轰 炸 卡 里 身 厨 房 x 聚 鑫 阁 岛 纯 聘 专 长 庄 鄉 更 珍 固 新 岩 v s m 至 尊 比 萨 广 披 饮 管 理 限 司 p 幸 东 正 挞 少 女 克 装 童 哒 磨 厂 怼 纤 入 户 独 溜 共 享 滋 江 门 九 蒸 胜 盛 & 魔 爪 鹅 皇 ( ) 友 甲 魚 首 烹 行 员 若 资 议 联 同 急 私 燕 儿 巢 鹏 记 腊 营 欢 迎 旗 舰 叫 了 做 故 铃 煎 饼 哥 力 五 谷 野 戈 厠 所 超 牌 冒 陳 陈 苕 爽 滑 启 秦 择 现 进 惊 喜 定 于 雅 膳 多 推 淇 淋 b 思 堡 偶 相 伴 呈 湯 绝 浏 ' 刘 态 牧 万 达 和 番 丼 — 机 瘦 绵 柔 厉 蚝 娘 彩 百 事 调 韩 爱 喝 玩 放 肆 寿 净 配 髓 非 道 额 吉 招 商 杂 粮 筐 运 转 服 务 缤 灿 腕 楠 彤 学 橋 试 浩 减 薪 诚 霸 第 间 日 极 料 開 業 霏 星 期 分 秒 内 咨 询 。 樐 头 开 氏 渔 约 劳 保 礼 宏 武 佘 轻 奢 艺 井 隆 鐵 卷 染 焙 钵 马 牟 洋 芋 片 流 宽 心 位 清 潼 关 祥 背 凡 哈 尔 滨 珠 派 艾 让 变 得 样 玖 等 综 性 涵 粗 冠 記 肠 湖 财 贡 桃 杭 平 桂 林 煨 档 案 造 潮 汕 宗 单 县 鲁 舜 脆 酥 糕 仕 十 临 簋 宴 字 太 灌 薄 尝 址 晗 幢 购 梁 醉 皖 庭 白 肥 块 石 碗 颜 值 張 瘾 跷 脚 而 叁 蜀 橙 市 边 早 晚 云 吞 目 表 赵 烩 擀 蔬 找 回 游 刃 余 支 洗 吹 休 闲 简 撸 根 据 鸽 铜 亲 贝 纪 吕 豚 饅 悦 汇 油 无 制 在 寻 碳 馋 嘴 架 荣 斋 护 角 落 铺 臊 丝 围 柳 蛳 蒲 庙 视 荐 缃 想 呀 姜 母 起 泉 族 群 众 其 它 血 双 补 阴 润 不 禽 类 款 较 候 些 畅 脉 痰 疏 肝 帮 助 消 增 欲 尤 对 胃 畏 寒 很 效 秘 黑 嘿 佳 越 脑 桶 项 ▪ | 榜 许 仿 或 酬 宾 指 买 赠 笃 鼎 盆 ™ 咕 咾 肚 识 栖 凤 渡 筒 彬 弟 醋 財 師 民 博 丁 扒 翅 墨 柠 檬 紫 薯 焗 芝 士 胸 图 妮 杀 菌 爹 尽 归 宁 粽 瑞 轩 午 陕 出 才 盘 植 甜 粒 神 舟 玻 璃 医 划 药 郡 毛 张 姐 留 满 下 兄 法 鋪 é [ 槑 ] 言 密 帝 場 朴 寨 奉 z 什 顺 疆 馕 豫 怀 旧 验 昙 搞 圣 格 ǐ à 隱 燙 状 居 饱 底 免 费 廣 點 專 門 语 叉 左 岸 发 乌 齐 冷 命 ● 修 闸 飞 空 养 笼 興 银 套 東 吴 麺 館 ¥ 从 前 乙 弘 炝 夏 秋 冬 咖 啡 ℃ © 莲 塘 哆 梓 依 哎 麦 泗 泾 瓯 胡 ∣ 歺 八 度 深 夜 旋 永 远 温 又 晶 溏 ä 盔 飘 劲 旺 楸 良 譜 餅 苏 莎 足 宵 与 楊 國 莱 卜 炊 挑 剔 存 错 方 程 解 能 堆 洲 诗 玛 渴 脖 丛 狼 翁 姓 葫 芦 沾 葵 の 咔 粹 弥 乖 悠 茗 别 走 柒 榨 咥 虹 沏 桔 叔 贴 办 充 崎 鮮 属 彭 浦 町 郎 ° 悟 惑 科 英 育 岁 幼 园 慢 摆 _ 狐 狸 典 暴 帥 尾 琼 見 望 烟 坚 鸳 鸯 直 校 饪 承 们 么 ¥ 份 宇 炉 峰 乃 趣 代 刨 抖 音 占 谜 答 熟 控 蕾 节 社 您 《 羅 茉 瀞 憨 尼 丰 镇 酿 避 抢 突 破 杰 姆 波 观 澜 庫 舒 谁 短 島 爷 码 每 欧 注 册 标 腸 奈 熊 粵 吳 衢 雄 际 葱 柱 压 陪 器 厘 柴 席 饿 俏 汽 站 霜 荟 禾 咘 臭 夷 肖 微 组 刺 拼 打 信 步 ! 说 囍 智 藍 鹿 巷 顾 勃 頭 帕 徐 渣 嗨 鲍 抽 莊 胗 耳 栈 葑 谊 李 够 歪 到 杜 绪 始 “ ” 编 感 谢 阿 妹 抄 屿 旁 钟 糰 鷄 觉 队 明 没 幺 罗 恭 發 溢 圆 筵 鲩 斤 噜 府 雕 牦 津 間 粤 义 驾 嫩 眷 苔 怡 逍 遥 即 把 季 鹃 妈 烙 淡 嘟 班 散 磐 稣 耍 芽 昌 粿 鼓 姑 央 告 翔 迦 缆 怪 俗 菩 宥 酵 男 顿 蚂 蚁 q 緑 瑩 養 滿 接 立 勤 封 徽 酷 ( 慕 曹 吊 咸 矿 黛 刻 呗 布 袋 钝 丘 逗 窗 吾 塔 坡 周 雙 朝 末 如 杨 淮 摄 影 翻 窝 物 椰 荞 搅 陇 收 两 倍 狮 伊 後 晖 長 箐 豪 耀 漢 釜 宮 次 掌 斯 朋 针 菇 蚬 拍 雒 陽 漿 麵 條 部 ← 柜 驴 证 票 账 汗 汆 稍 戏 菋 卫 匹 栋 馨 肯 迪 邢 梯 容 嘉 莞 袁 锦 遮 雨 篷 腰 肺 剡 乾 , 翰 蔚 刁 藤 帅 傳 维 笔 历 史 】 适 煌 倾 沧 姬 训 邵 诺 敢 质 益 佬 兼 职 盅 诊 扬 速 宝 褚 糁 钢 松 婚 秀 盐 及 個 飲 绍 槿 觅 逼 兽 》 吐 右 久 闺 祝 贺 啦 瓦 甏 探 辰 碚 芳 灣 泷 饰 隔 帐 飮 搜 時 宫 蘭 再 糊 仓 稻 玉 印 象 稀 拴 桩 餃 贾 贱 球 萌 撕 脂 肪 层 晋 荷 钱 潍 失 孜 提 供 具 洛 涂 叠 豊 积 媒 级 纷 巧 瓜 苹 琥 珀 蜂 柚 莉 爆 龄 饸 饹 郞 嫡 億 姚 繁 监 督 示 佰 汍 % 甘 蔗 喻 骄 基 因 匙 评 侠 赢 交 歡 待 馒 产 倡 导 低 茂 沐 熙 延 丧 受 确 睡 蓝 未 賣 電 話 农 札 岗 树 赖 琪 驻 辉 软 防 盗 隐 形 纱 灶 扎 环 禁 止 吸 萬 昆 几 跳 媳 婦 坛 < > 拿 妖 协 朱 住 宿 魅 照 碰 滴 何 贤 棒 持 啊 赛 版 帆 順 狗 情 + 洞 奋 斗 亨 叶 涛 铝 范 汀 號 律 價 鞭 肩 # 愚 奥 脯 沁 奚 魏 批 租 宠 炲 横 沥 彪 投 诉 犀 去 屠 鲅 ~ 俱 徒 鴻 劉 迷 荤 威 曜 連 鎖 馳 载 添 筑 陵 佐 敦 > 郭 厢 祛 茄 堰 漂 亮 爅 虎 膀 叼 猫 藏 陶 鲈 栏 … 考 冲 胖 裕 沃 挂 报 兔 胶 臨 附 处 嫂 萃 幂 吻 聪 糯 糍 棋 烓 脊 衡 亚 副 肤 荆 榴 绚 黔 圈 纳 课 逸 宜 = 烊 姨 施 救 贸 啥 也 贯 雷 呆 棠 伙 岐 宛 媽 寸 澳 已 還 兒 Ⅱ 凯 株 藕 闽 窖 瀘 售 索 体 型 樂 琅 琊 夺 扩 ) 诱 滩 浓 要 芹 君 反 复 羔 追 演 唱 過 綫 乳 涩 芒 露 蒙 羯 励 志 嵊 閒 罐 佛 墙 頁 坐 眯 预 華 廉 释 必 随 逐 引 究 爸 灵 勺 岂 俵 廷 苗 岭 将 來 泛 朵 維 園 廳 圳 伦 寶 付 仅 減 谦 硕 抚 慶 雞 郝 计 熱 杖 亭 喱 惜 莒 另 陆 拾 伍 谈 嚼 娅 翟 別 颈 邮 弄 • 扇 哦 吼 耶 宅 帽 魂 搭 笨 映 拨 烂 馈 胎 溶 \ 善 销 难 忘 斑 噢 錫 娟 語 哨 筷 摊 均 椅 改 换 跟 帖 勾 缅 孙 啪 栗 着 漁 吓 易 漲 靖 枸 馬 昇 當 麥 妆 塑 魯 鎮 吗 魁 丹 杈 技 术 泼 零 忙 漾 創 攀 郫 抿 稼 假 循 泳 池 膨 巨 歧 愛 鵝 悉 灯 激 踪 细 會 舔 愿 們 衹 令 浔 丨 酉 惦 耕 × 闪 經 玺 芯 襄 賦 予 學 苑 托 丢 赔 ā 聽 濤 浮 伯 兑 币 治 愈 盱 眙 漏 夕 搏 由 完 切 罕 息 燃 叙 萍 碑 腌 衣 害 己 患 浙 闫 | 芈 谣 戴 錦 謝 恩 芊 拇 矾 政 锣 跃 钥 寺 驼 芙 插 恒 咪 禄 摩 轮 譚 鴨 戊 申 丙 邊 唯 登 困 貢 誉 賀 认 准 妃 潜 旨 死 桌 尧 箱 届 获 顶 柿 臂 蓮 凭 慵 懒 醇 籍 静 淌 此 甚 绣 渌 呢 问 抹 弹 捷 邱 旦 曉 艳 雲 研 守 鼻 ¦ 揽 含 沂 听 帛 端 兆 舆 谐 帘 笑 寅 【 車 @ & 胪 臻 蘆 衙 餌 ① 鉴 敬 枝 沈 衔 蝉 芜 烈 库 椿 稳 ’ 豌 亿 缙 獨 菊 沤 迟 忧 沫 伟 靠 并 互 晓 枫 窑 芭 夯 鸿 無 烦 恼 闖 贞 鳥 厦 抱 歐 藝 廖 振 腦 舖 酪 碎 浪 荔 巫 撈 醬 段 昔 潘 Λ 禧 妻 瓢 柏 郁 暹 兮 娃 敏 進 距 离 倪 征 咱 继 责 任 銅 啖 赞 菲 蛇 焰 娜 芮 坦 磅 薛 緣 乔 拱 骚 扰 約 喷 驢 仨 纬 臘 邳 终 喏 扫 除 恶 争 率 ‘ 肃 雀 鈴 贼 绕 笋 钩 勒 翠 黎 董 澄 境 采 拳 捆 粄 诸 暨 榧 葛 親 戚 访 股 融 潤 寄 递 藩 滇 湛 他 篓 普 撞 莅 但 沟 暑 促 玲 腩 碼 偏 楹 嘎 洒 抛 危 险 损 负 銘 黃 燜 說 杆 称 蹭 聊 妙 滕 曦 肴 萧 颗 剂 義 锋 授 权 著 茴 蒝 侬 顏 菁 擦 鞋 庞 毕 谱 樱 → 綦 舞 蹈 躁 渠 俐 涧 馀 潇 邻 须 藻 纺 织 军 沅 豐 爐 韭 棚 綿 麯 剑 娱 链 锤 炼 献 晟 章 謎 数 侯 她 疗 途 篇 则 邓 赐 閣 對 猩 邑 區 鬼 莫 沪 淼 赤 混 沌 需 求 痛 绮 琦 荃 熳 佑 Á ō 現 専 卢 譽 缠 曾 鸣 琴 汊 濮 哇 哩 唝 曲 坂 呼 莴 怕 蒋 伞 炙 燻 瑧 冈 讲 硬 详 鹵 摇 偃 嵩 严 谨 ′ 剥 穗 榮 禹 颐 局 刚 ▕ 暖 漠 炎 頤 樟 ? 储 移 缕 艰 袍 瑪 麗 参 䬺 趁 呦 霖 饵 溪 孔 澤 袜 蔓 熠 显 屏 缇 寇 亞 坑 槟 榔 絳 驿 歹 匾 猴 旭 竞 ­ 唛 介 习 涡 寓 掉 蘸 愉 佼 ǒ 納 ∶ 革 嚸 募 螃 鲢 俤 扁 寳 辽 ∧ 厚 裤 扯 屯 废 挪 辘 碉 歇 漓 腻 捣 孩 烁 整 按 Ⓡ 眉 脸 痣 粑 序 穿 樊 玮 ★ 扑 渊 醴 瑶 農 檔 憩 霊 赫 呜 ~ 备 説 莓 钻 播 冻 紅 菽 喪 埔 壽 ❤ 籽 咻 籣 尹 潭 穆 壮 使 霄 蔵 浒 岳 熘 臺 殷 孤 邂 逅 厕 郸 铭 莆 抻 虽 倦 怠 矣 茵 垂 殿 鄂 嗑 续 钦 党 鲫 蔡 侧 割 彰 凝 熬 叕 純 谛 籠 宋 峡 俩 雜 跑 ⑧ 焼 - 逢 澧 舵 异 冯 战 决 棍 ; ﹣ 丑 妇 焉 芷 楂 坞 壳 馐 帜 旅 鳯 簡 凍 秜 结 咩 丫 稠 暗 缔 乎 被 狠 皲 豉 崇 渭 担 鹤 製 蛎 笛 奔 赴 盼 鳌 拜 络 灸 膜 刮 痧 毒 萊 陂 濑 唇 抵 押 置 馇 泌 尿 傻 像 孃 陣 靓 规 企 矮 凳 贰 兎 庵 質 阅 读 ◆ 练 墩 曼 呱 泓 耐 磁 枣 罉 浴 氧 洱 鳅 線 炳 顽 符 倌 泥 郊 柯 餘 巍 论 沽 荘 奕 啃 髙 ○ 芬 苟 且 阆 確 獅 匣 睫 牙 戒 俊 阜 遵 爵 遗 捧 仑 构 豬 挡 弓 蠔 旬 鱻 镖 燚 歌 壁 啫 饷 仰 韶 勞 軒 菒 炫 廊 塞 脏 堤 浅 辈 靡 裙 尺 廚 向 磊 咬 皓 卿 懂 葉 廿 芸 賴 埠 應 碟 溧 訂 選 睦 举 钳 哟 霍 扞 侣 營 龟 钜 埭 が 搽 螞 蟻 娚 蒜 厝 垵 ☎ 捌 倒 骑 Ξ 谋 黍 侍 赏 扮 忱 蘑 洁 嘆 闹 谭 鶏 種 φ 坤 麓 麒 麟 喂 琳 Ⓑ 趙 總 這 奖 取 拔 錯 仉 缸 廟 暢 腔 卓 腱 朙 紹 莹 缺 抺 睿 氣 该 貼 妍 拆 穇 箩 希 廰 祗 盲 坝 骆 熄 蛮 賓 馮 尋 泊 孫 槁 亖 俯 浣 婴 锨 馥 闷 梆 ▫ 姥 哲 录 甫 床 嬌 烎 梵 枪 乍 璜 羌 崂 穷 榕 聲 喚 駕 晕 嬷 箕 婧 盧 楓 柃 差 「 」 佶 唔 壕 歆 盏 擂 睇 巾 查 淖 哪 沣 赣 優 諾 礁 努 畔 疙 瘩 握 叮 栙 甑 嶺 涌 透 钓 斜 搬 迁 妨 借 仍 鳕 瓷 绘 餠 á ǎ 祈 邨 醒 闵 砖 锹 咀 綠 幕 忠 雾 覓 靜 擔 篮 杉 势 薇 甬 频 般 仲 蘇 鸟 卞 憾 資 駱 蝶 為 仟 耗 莘 涉 昕 盈 熹 觀 瑭 湃 兢 淞 䒩 結 柗 鲤 糟 粕 塗 簽 怎 桐 皆 羽 盯 氽 晏 液 镀 珂 悸 ∙ 桑 夢 楽 剩 纵 逝 欺 統 飛 姣 俄 揪 薡 幅 蓋 ︳ 屉 㕔 а 铸 韦 銀 檀 击 伿 隍 『 』 芥 ☆ 声 跆 肋 榭 牵 棧 網 愁 嗏 嵗 巡 稚 貴 買 恰 㸆 捻 玫 瑰 炕 梧 餡 锌 焱 驰 堽 邯 珑 尕 宰 栓 喃 殊 燊 慈 羴 逃 脱 邹 檐 碌 页 荠 券 題 龚 肌 蕉 囬 肫 坪 沉 淀 斌 鳝 核 喳 剃 昭 { } 坏 烜 媛 猛 桓 欣 碁 竭 堇 ↑ 扛 罄 栾 鲶 鍕 崔 橘 携 丈 射 梗 檸 疼 卑 捉 障 裏 遍 蓓 析 許 虫 坨 馔 窄 姫 噤 係 湿 汐 鳜 船 崽 + 例 灼 祿 腥 峭 酌 喽 件 郏 栀 鲨 寫 與 诈 斥 炮 稿 懿 掂 鹭 乱 恬 婷 苦 埃 珊 禅 裹 圃 鹌 鹑 û 澡 囧 阡 靑 警 牢 嘱 鳞 浃 贷 慧 翊 讨 碧 剪 陌 冀 砵 迅 鹰 竟 召 敌 鯡 蒌 蒿 扶 ③ 誘 嘻 輪 嬢 瓮 絲 嚣 荀 莽 鄧 咋 勿 佈 洽 羹 模 貨 粱 凈 腹 鄭 署 儒 隧 鉢 茫 蔻 í ó 裴 偉 Θ 祎 褥 殖 湫 瀚 貓 汪 紙 極 伤 灰 團 橄 榄 拽 响 貌 傣 舂 斩 飨 执 諸 蒂 嘣 葡 渤 惺 驛 戰 箬 俭 瀏 嫦 琵 琶 咿 吖 舱 韵 揭 祁 將 軍 吟 彼 岚 绒 煤 淝 歸 锐 嗯 傾 甩 瞳 睁 鳗 遜 嗲 虚 娴 碱 呷 { 哚 兜 喇 叭 燦 逻 匪 槐 撒 写 踩 踏 霞 喫 返 赚 拓 動 觞 鲽 鐘 闰 扳 沖 賈 璐 煸 棵 峪 π 憶 齋 娇 穎 嫁 玥 胚 喊 阻 餓 截 孵 屎 爾 莳 倔 娄 祸 ` 姿 稽 戌 缪 ī 糠 痴 猎 嬉 柑 鞍 兹 凼 舅 褐 醪 仪 氷 單 丞 碛 绽 袂 檢 瀾 饃 孖 雍 ò 螄 涤 茨 寮 近 辜 茅 孟 累 宣 樹 鷹 膝 臉 襪 嘢 嵐 ▲ 璇 竺 気 迈 糐 挥 瑜 伽 " 裳 纹 潯 幾 朔 枊 釀 劝 俺 粢 馓 胥 拥 嘶 達 蝴 昱 ホ ル モ ニ 颂 噫 否 笙 绎 俞 泵 测 耿 揚 犇 锄 卧 炯 烽 橡 操 齊 隴 宀 荥 滙 贪 関 垦 ↓ 麽 暧 匯 恨 叽 断 鮪 椎 病 迹 禺 搓 瀛 唤 埕 愤 怒 拐 狱 垅 绅 設 計 書 楷 鮨 邪 郴 盞 榆 恺 樵 煙 舫 翡 砸 叹 縣 璞 禮 獻 似 吆 嘛 灭 擇 夥 ē 曰 蜗 櫻 ▏ 鑪 鯊 視 淄 钰 〝 〞 報 退 壶 鳴 拒 旱 鼠 蕴 峧 赶 咏 寬 渎 靣 卟 宙 趟 負 镫 讷 迭 彝 樣 輕 却 覆 庖 扉 聖 喬 瞻 瞿 箭 胆 ε 韧 誌 既 淳 饞 ě 圍 墟 俚 翕 貂 畜 緹 搄 旮 旯 寂 寞 詹 茜 鉄 絕 泸 嬤 允 炘 骏 侑 晒 玄 粧 糘 毫 幽 攸 愧 侨 衰 ぉ に き ぃ 炽 倉 斛 領 盾 窜 鲷 瓏 媚 爲 裸 窦 虞 處 魷 } 羡 冕 祺 裁 粶 䬴 嚟 辆 撮 隋 ' 勝 梭 茸 咭 崟 滷 緻 沩 颠 诠 珺 拙 察 ≡ 辅 父 雁 裱 瞄 漖 鯨 略 橱 帼 棉 濠 蕃 ǔ 崮 阮 勋 苍 喔 猜 箔 è 雏 睐 袭 皋 彻 売 垚 咯 凑 汴 纽 巩 宸 墅 茏 裡 昧 飽 坯 濟 └ ┐ 懷 霾 ´ 閑 茹 闳 湶 鈣 圓 昊 眞 標 凖 皱 箍 筹 孬 唠 輝 输 綺 驭 哼 匡 偵 蝇 運 漟 乘 Ē 卉 邴 謠 怿 亁 棱 呐 湄 莜 阶 堔 炜 邀 笠 遏 犯 罪 栢 餛 亀 苓 膏 伸 ? 阪 委 妯 娌 仝 咧 鍚 ▼ 遠 摑 滘 颁 ʌ 锈 佤 佗 卌 É ↙ 蔺 汰 塍 認 鳟 畿 耦 吨 䒕 茬 枼 饕 涼 烀 汶 齿 貳 沱 楞 屹 掺 挢 荻 偷 辶 饌 泮 喧 某 聂 夾 吁 鎬 谅 鞘 泪 佩 ㎡ 鐡 犊 漳 睢 粘 輔 爬 濃 し ん い ち ょ く ど ぅ 戍 咚 蒡 惯 隣 沭 撇 妞 筛 昵 赁 震 欠 涞 從 靚 绥 俑 熔 曙 侗 √ 仗 袖 饶 辫 琉 鴿 裂 缝 灞 崖 炑 昝 ┌ ┘ 邕 趴 踢 迩 浈 挚 聆 犁 陝 滾 彎 問 癮 砚 ú 瀧 吮 毓 劵 槽 黒 忍 畈 姊 沛 忽 摘 燍 ♡ 汝 贛 叻 甸 乞 丐 践 嗞 㥁 斐 圖 祯 牤 攻 弯 幹 杠 苞 滤 筆 練 鞑 ˊ 萤 榶 叨 轨 耒 嚮 ┃ 漪 剛 键 弋 彦 瘋 词 敖 鸦 秧 囚 绾 镶 濂 ↘ 豁 煒 萄 珲 緋 昂 瀨 缓 疲 替 汥 殡 葬 靳 揉 闭 睛 偘 佚 $ ; ^ """ end end