Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add learn from ai #542

Merged
merged 5 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 103 additions & 2 deletions .cache/resource-pool.json

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

plus:
- [ ] https://conv.denshochan.com/markdown
- [ ] 段落内の改行
- [ ] 行頭の文字下げ
- [ ] Twitter アカウント
- [ ] ルビ
- [ ] ものルビ風の熟語ルビ
- [ ] https://www.haxibami.net/blog/posts/blog-renewal
- [ ] link card
- [ ] image to next image https://zenn.dev/elpnt/articles/c17727e9d254ef00ea60
- [ ] precompile mermaid
- [ ] svg 输入
- [ ] 绘画工具: KRITA , 免费,有 mac os 版 https://docs.krita.org/zh_CN/user_manual.html
- [ ] KRITA 推荐使用 Inkscape 进行编辑
- [ ] vscode 语法站内相对链接
- [ ] mui/base could be very good
- [ ] search lunr? -> mini search https://www.webpro.nl/articles/how-to-add-search-to-your-static-site
- [ ] 可以简单参考 3b1b 直接全局 hold 住,然后全文搜索
- [ ] blog list pagition (could be later, use infinite scroll)
- [ ] nextjs 13 app directory https://beta.nextjs.org/docs/getting-started
- [ ] ja 等多语言支持
- [ ] 基于 git 的差量 build
- [ ] 组件 visual testing https://glebbahmutov.com/blog/open-source-visual-testing-of-components/
- [x] gh-pages gls 不可能,不支持
- [x] gh-pages public paths
- [ ] search console?
- [ ] 参考以下链接优化主页
- [ ] https://meola.booth.pm/items
- [ ] https://makoto-kaminaga.jimdofree.com/

- [ ] Tag slug 页面 hardcoded postType
- [ ] Obsidian 站内引用
- [ ] Obsidian Tips Block
1 change: 1 addition & 0 deletions learn_from_ai
34 changes: 1 addition & 33 deletions public/content/ideas/blog-in-next.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ tags:
- [x] favicon
- [x] Google Analytics
- [ ] sitemap 检查
- [ ] test workflow for dependabot
- [x] test workflow for dependabot
- [x] SEO better, og:type=article read more: https://ogp.me/#types
- [x] 文章按创建时间倒序
- [x] 写 README 与项目简介
Expand All @@ -131,35 +131,3 @@ tags:
- md syntax -> special html -> use rehype plugin rewriting (katex, highlight)
- special md syntax -> use remark plugin rewriting (could not to mdx, should first to html and then mdx provider rewrite)


plus:
- [ ] https://conv.denshochan.com/markdown
- [ ] 段落内の改行
- [ ] 行頭の文字下げ
- [ ] Twitter アカウント
- [ ] ルビ
- [ ] ものルビ風の熟語ルビ
- [ ] https://www.haxibami.net/blog/posts/blog-renewal
- [ ] link card
- [ ] image to next image https://zenn.dev/elpnt/articles/c17727e9d254ef00ea60
- [ ] precompile mermaid
- [ ] svg 输入
- [ ] 绘画工具: KRITA , 免费,有 mac os 版 https://docs.krita.org/zh_CN/user_manual.html
- [ ] KRITA 推荐使用 Inkscape 进行编辑
- [ ] vscode 语法站内相对链接
- [ ] mui/base could be very good
- [ ] search lunr? -> mini search https://www.webpro.nl/articles/how-to-add-search-to-your-static-site
- [ ] 可以简单参考 3b1b 直接全局 hold 住,然后全文搜索
- [ ] blog list pagition (could be later, use infinite scroll)
- [ ] nextjs 13 app directory https://beta.nextjs.org/docs/getting-started
- [ ] ja 等多语言支持
- [ ] 基于 git 的差量 build
- [ ] 组件 visual testing https://glebbahmutov.com/blog/open-source-visual-testing-of-components/
- [x] gh-pages gls 不可能,不支持
- [x] gh-pages public paths
- [ ] search console?
- [ ] 参考以下链接优化主页
- [ ] https://meola.booth.pm/items
- [ ] https://makoto-kaminaga.jimdofree.com/


333 changes: 333 additions & 0 deletions public/content/learn_from_ai/2024-11-29-deep-learning-model-formats.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
created_at: 2024-11-29 11:00:00+08:00
updated_at: 2024-11-29 11:00:00+08:00
title: OpenCV 坐标表示:理解 (y, x) 与 (x, y) 的区别
license: true
tags:
- OpenCV
- 图像处理
- 学习笔记
---

> 📝 本文是我在学习 OpenCV 时遇到的一个问题。问题的解答和中文翻译均由 AI 生成。

# OpenCV 坐标表示:理解 (y, x) 与 (x, y) 的区别

## Q
Why sometimes opencv represent a point coordinate as (y,x) (e.g. the result of cv2.findContours) , and sometimes it represent as (x, y) (e.g. the arg `center` of cv2.circle)?

> 为什么 OpenCV 有时用 (y,x) 表示坐标点(比如 cv2.findContours 的返回值),有时又用 (x,y) 表示(比如 cv2.circle 函数的 `center` 参数)?

## A
OpenCV uses different conventions for different functions based on their specific requirements and historical reasons:

> OpenCV 基于不同函数的具体需求和历史原因,使用了不同的坐标表示约定:

1. **(y, x) Convention**: This is often used when dealing with image matrices directly. In image processing, images are typically represented as 2D arrays where the first dimension is the row (height, y-coordinate) and the second dimension is the column (width, x-coordinate). Functions like `cv2.findContours` return coordinates in this order to match the array indexing.

> 1. **(y, x) 约定**:这种表示方法通常用于直接处理图像矩阵时。在图像处理中,图像通常表示为二维数组,其中第一维是行(高度,y坐标),第二维是列(宽度,x坐标)。像 `cv2.findContours` 这样的函数返回这种顺序的坐标是为了匹配数组索引方式。

2. **(x, y) Convention**: This is used in functions that deal with geometric shapes or points in a more traditional Cartesian coordinate system, where `x` is the horizontal axis and `y` is the vertical axis. Functions like `cv2.circle` use this convention to specify the center of the circle.

> 2. **(x, y) 约定**:这种表示方法用于处理几何图形或在传统笛卡尔坐标系中的点,其中 `x` 是水平轴,`y` 是垂直轴。像 `cv2.circle` 这样的函数使用这种约定来指定圆心位置。

The inconsistency arises because OpenCV aims to balance between image matrix operations and geometric operations, each having their own conventional coordinate systems.

> 这种不一致性的出现是因为 OpenCV 需要在图像矩阵运算和几何运算之间取得平衡,而这两种运算各自有其传统的坐标系统表示方法。
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ describe("test tag index", () => {
];
const builder = new TagIndexBuilder();
input.forEach((item) => {
builder.addResource("articles", item); // TODO 不合理,后面修改 tagIndex 时需修改
const resourceType = item.pathMapping.pagePath.split("/")[1];
builder.addResource(resourceType, item);
});

type GetSlugCase = {
name: string;
input: string;
output: Array<{
postType: "article" | "idea";
postType: string;
postSlug: string;
postPagePath: string;
}>;
Expand All @@ -55,24 +56,28 @@ describe("test tag index", () => {
input: "abc",
output: [
{
postType: "article",
postType: "articles",
postSlug: "001",
postPagePath: "/articles/001",
},
{
postType: "idea",
postType: "ideas",
postSlug: "001",
postPagePath: "/ideas/001",
},
{ postType: "idea", postSlug: "002", postPagePath: "/ideas/002" },
{
postType: "ideas",
postSlug: "002",
postPagePath: "/ideas/002",
},
],
},
{
name: "should parse tag 2",
input: "cde",
output: [
{
postType: "article",
postType: "articles",
postSlug: "001",
postPagePath: "/articles/001",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,40 @@

import { BaseMeta, PagePathMapping, Resource } from "../../../types/indexing";
import { IndexBuilder, getIndexFromIndexPool } from "../index-building";
import { TagInfo, postPathMappingToPostSlugInfo } from "./types";
import { PostSlugInfo, TagInfo } from "./types";

/**
* Converts a tag string to a URL-friendly slug
* e.g. "Machine Learning" -> "machine-learning"
*/
const tagToTagSlug = (tag: string) => {
return tag.toLowerCase().replace(" ", "-").replace("/", "-");
};

/**
* Generates the URL path for a tag page
* e.g. "machine-learning" -> "/tags/machine-learning"
*/
const tagSlugToPath = (tagSlug: string) => {
return `/tags/${tagSlug}`;
};

/**
* Converts a page path mapping to post slug info
* Combines the resource type (e.g. "articles") with the page path mapping
* to create a unique identifier for a post
*/
const postPathMappingToPostSlugInfo = (
resourceType: string,
pathMapping: PagePathMapping
): PostSlugInfo => {
return {
postType: resourceType,
postSlug: pathMapping.slug,
postPagePath: pathMapping.pagePath,
};
};

export type TagIndexMeta = BaseMeta & {
tags: string[];
};
Expand All @@ -36,23 +61,43 @@ export class TagIndexBuilder
this.index = new Map();
}

/**
* Adds a resource to the tag index
* For each tag in the resource's metadata:
* - Creates a new TagInfo if the tag doesn't exist
* - Adds the post's slug info to the tag's list of posts
*
* 不合理:应用 path 作键而不是 slug 或 name 作键
*/
addResource = (
resourceType: string,
resource: Resource<PagePathMapping, TagIndexMeta>
) => {
const { slug: postSlug } = resource.pathMapping;
const { tags } = resource.meta;
tags.forEach((tag) => {
const slug = tagToTagSlug(tag);
if (!this.index.has(slug)) {
const tagPath = tagSlugToPath(slug);
this.index.set(slug, { tag, slug, path: tagPath, postSlugs: [] });
const tagSlug = tagToTagSlug(tag);
if (!this.index.has(tagSlug)) {
const tagPath = tagSlugToPath(tagSlug);
this.index.set(tagSlug, {
tag,
slug: tagSlug,
path: tagPath,
postSlugs: [],
});
}
const postSlugInfo = postPathMappingToPostSlugInfo(resource.pathMapping);
this.index.get(slug)?.postSlugs.push(postSlugInfo);
const postSlugInfo = postPathMappingToPostSlugInfo(
resourceType,
resource.pathMapping
);
this.index.get(tagSlug)?.postSlugs.push(postSlugInfo);
return;
});
};

/**
* Builds and returns the final tag index
* Returns an object with a single "tag" key containing the TagIndex instance
*/
buildIndex = async () => {
return {
tag: new TagIndex(this.index),
Expand All @@ -66,13 +111,26 @@ export class TagIndex {
constructor(index: Map<string, TagInfo>) {
this.index = index;
}

/**
* Gets all posts that have the given tag
*/
getPostSlugs(tag: string) {
const tagSlug = tagToTagSlug(tag);
return this.index.get(tagSlug)?.postSlugs || [];
}

/**
* Gets all tags in the index
*/
getTags() {
return Array.from(this.index.values());
}

/**
* Gets TagInfo objects for the given tag strings
* Returns only tags that exist in the index
*/
getTagsOf(tags: string[]) {
const tagSlugs = tags.map(tagToTagSlug);
let result: TagInfo[] = [];
Expand All @@ -85,5 +143,8 @@ export class TagIndex {
return result;
}

/**
* Gets a TagIndex instance from the index pool
*/
static fromPool = getIndexFromIndexPool<TagIndex>("tag");
}
30 changes: 2 additions & 28 deletions src/core/indexing/index-building/tag-index-builder/types.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,9 @@
import { PagePathMapping } from "@/core/types/indexing";

type PostType = "article" | "idea";

type PostSlugInfo = {
postType: PostType;
export type PostSlugInfo = {
postType: string;
postSlug: string;
postPagePath: string;
};

/**
* 不合理,
* 1. tagInfo 本身应与 post 无关
* 2. 应用 path 作键而不是 slug 或 name 作键
*
* 先保持接口不变性,后续再进行外部重构
*/
export const postPathMappingToPostSlugInfo = (
pathMapping: PagePathMapping
): PostSlugInfo => {
const postType: "article" | "idea" = pathMapping.pagePath.startsWith(
"/articles"
)
? "article"
: "idea";
return {
postType,
postSlug: pathMapping.slug,
postPagePath: pathMapping.pagePath,
};
};

export type TagInfo = {
tag: string;
slug: string;
Expand Down
6 changes: 6 additions & 0 deletions src/core/indexing/indexing-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ export const ideaResourceMap = () => {
"ideas"
);
};
export const learnFromAiResourceMap = () => {
return getResourceMap<PagePathMapping, PostMeta>(
mustGetCache().resourcePool,
"learn_from_ai"
);
};
export const getTagIndex = () => {
return TagIndex.fromPool(mustGetCache().indexPool);
};
Expand Down
24 changes: 21 additions & 3 deletions src/core/indexing/indexing-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export function ideaPostPathMapper() {
});
}

export function learnFromAiPostPathMapper() {
return new PostPathMapper({
fileGlobPattern: "public/content/learn_from_ai/*.md*",
slugFromFilename: (filename) => filename.match(/(\d*-)*(.*)/)?.[2],
pathPrefix: "/learn_from_ai/",
});
}

export const defaultStaticResourceChain: MetaCollectorChain<BaseMeta> = {
collectors: [],
defaultMeta: {},
Expand Down Expand Up @@ -82,18 +90,28 @@ export const pipeline = () => ({
pathMapper: ideaPostPathMapper(),
collectorChain: defaultChain,
},
{
resourceType: "learn_from_ai",
pathMapper: learnFromAiPostPathMapper(),
collectorChain: defaultChain,
},
],
indexBuilders: [
{
handleResources: ["articles", "ideas"],
handleResources: ["articles", "ideas", "learn_from_ai"],
builder: new TagIndexBuilder(),
},
{
handleResources: ["articles", "ideas", "staticResources"],
handleResources: [
"articles",
"ideas",
"learn_from_ai",
"staticResources",
],
builder: new AliasIndexBuilder(),
},
{
handleResources: ["articles", "ideas"],
handleResources: ["articles", "ideas", "learn_from_ai"],
builder: new PrevNextIndexBuilder(),
},
{
Expand Down
Loading