<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>printf(&amp;quot;ho_tari\n&amp;quot;);</title>
    <link>https://hotari.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 20 Jun 2026 00:49:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>호타리</managingEditor>
    <image>
      <title>printf(&amp;quot;ho_tari\n&amp;quot;);</title>
      <url>https://tistory1.daumcdn.net/tistory/6602731/attach/6af4dab649444e0b866d9eb133a48b29</url>
      <link>https://hotari.tistory.com</link>
    </image>
    <item>
      <title>19일차</title>
      <link>https://hotari.tistory.com/544</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.29&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스 드라이버 개발 환경 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/rotary_encoder-23f27600c1fd80f68259ec875849c89d?source=copy_link&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.notion.so/rotary_encoder-23f27600c1fd80f68259ec875849c89d?source=copy_link&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스 드라이버 rotary_encoder 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Makefile&lt;/p&gt;
&lt;pre id=&quot;code_1753835966651&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj-m += rotary_encoder.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rotary_encoder.c&lt;/p&gt;
&lt;pre id=&quot;code_1753835954894&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/kernel.h&amp;gt;
#include &amp;lt;linux/init.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;
#include &amp;lt;linux/gpio.h&amp;gt;
#include &amp;lt;linux/interrupt.h&amp;gt;
#include &amp;lt;linux/cdev.h&amp;gt;
#include &amp;lt;linux/uaccess.h&amp;gt;
#include &amp;lt;linux/device.h&amp;gt;
#include &amp;lt;linux/timer.h&amp;gt; // 커널 타이머 헤더 추가

// --- 장치 이름 및 주 번호 설정 ---
#define DEVICE_NAME &quot;rotary_dev&quot;

// --- GPIO 핀 설정 (BCM GPIO 번호 기준) ---
#define LED0_GPIO   538
#define LED1_GPIO   531
#define LED2_GPIO   525
#define LED3_GPIO   518
#define LED5_GPIO   533
#define LED6_GPIO   532
#define LED7_GPIO   528

#define ROTARY_CLK_GPIO 529
#define ROTARY_DT_GPIO  539
#define KEY_SWITCH_GPIO 534

#define DEBOUNCE_TIME_MS 50 // 디바운싱 시간 (50ms)

// --- 전역 변수 ---
static int rotary_count = 0;
static int led5_state = 0;
static dev_t dev_num;
static struct cdev rotary_cdev;
static struct class *rotary_class;
static struct device *rotary_device;

// 인터럽트 관련
static int rotary_irq_clk;
static int key_switch_irq;
static int last_rotary_clk_state;
static unsigned long last_rotary_irq_time = 0;

// 디바운싱을 위한 커널 타이머
static struct timer_list debounce_timer;

// ... (이전 코드의 함수 선언, 파일 연산 구조체, LED 업데이트 함수 등은 동일) ...
static int rotary_open(struct inode *, struct file *);
static int rotary_release(struct inode *, struct file *);
static ssize_t rotary_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t rotary_write(struct file *, const char __user *, size_t, loff_t *);
static long rotary_ioctl(struct file *, unsigned int, unsigned long);

static const struct file_operations rotary_fops = {
    .owner   = THIS_MODULE,
    .open    = rotary_open,
    .release = rotary_release,
    .read    = rotary_read,
    .write   = rotary_write,
    .unlocked_ioctl = rotary_ioctl,
};

static void update_led_display(int value) {
    value = value % 16;
    if (value &amp;lt; 0) value += 16;
    gpio_set_value(LED0_GPIO, (value &amp;amp; 0x01) ? 1 : 0);
    gpio_set_value(LED1_GPIO, (value &amp;amp; 0x02) ? 1 : 0);
    gpio_set_value(LED2_GPIO, (value &amp;amp; 0x04) ? 1 : 0);
    gpio_set_value(LED3_GPIO, (value &amp;amp; 0x08) ? 1 : 0);
}


// --- Rotary Encoder 인터럽트 핸들러 (이전과 동일) ---
static irqreturn_t rotary_encoder_isr(int irq, void *dev_id) {
    unsigned long current_time = jiffies;
    if (time_after(current_time, last_rotary_irq_time + msecs_to_jiffies(2))) {
        int current_clk_state = gpio_get_value(ROTARY_CLK_GPIO);
        if (current_clk_state != last_rotary_clk_state) {
            int dt_state = gpio_get_value(ROTARY_DT_GPIO);
            if (current_clk_state == 0) {
                if (dt_state == 1) { rotary_count++; gpio_set_value(LED7_GPIO, 1); gpio_set_value(LED6_GPIO, 0); }
                else { rotary_count--; gpio_set_value(LED7_GPIO, 0); gpio_set_value(LED6_GPIO, 1); }
                update_led_display(rotary_count);
            }
        }
        last_rotary_clk_state = current_clk_state;
        last_rotary_irq_time = current_time;
    }
    return IRQ_HANDLED;
}

// --- 디바운싱 타이머 콜백 함수 (NEW) ---
static void debounce_timer_callback(struct timer_list *t) {
    // 타이머가 만료된 시점의 버튼 상태를 다시 확인
    int current_state = gpio_get_value(KEY_SWITCH_GPIO);

    // 여전히 눌려있다면(LOW), 유효한 누름으로 간주하고 토글 실행
    if (current_state == 0) {
        led5_state = !led5_state;
        gpio_set_value(LED5_GPIO, led5_state);
        printk(KERN_INFO &quot;Key Switch: Valid press detected, LED5 toggled to %s\n&quot;, led5_state ? &quot;ON&quot; : &quot;OFF&quot;);
    }

    // 다음 입력을 받을 수 있도록 인터럽트를 다시 활성화
    enable_irq(key_switch_irq);
}

// --- Key Switch 인터럽트 핸들러 (MODIFIED) ---
static irqreturn_t key_switch_isr(int irq, void *dev_id) {
    // 인터럽트가 발생하면, 추가적인 바운싱을 막기 위해 인터럽트를 즉시 비활성화
    disable_irq_nosync(key_switch_irq);

    // 디바운싱 타이머를 현재로부터 DEBOUNCE_TIME_MS 이후로 설정
    mod_timer(&amp;amp;debounce_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME_MS));

    return IRQ_HANDLED;
}


// ... (장치 파일 연산 함수들은 이전과 동일) ...
static int rotary_open(struct inode *inode, struct file *file) { return 0; }
static int rotary_release(struct inode *inode, struct file *file) { return 0; }
static ssize_t rotary_read(struct file *file, char __user *buf, size_t count, loff_t *pos) {
    int len; char kbuf[20];
    if (*pos &amp;gt; 0) return 0;
    len = scnprintf(kbuf, sizeof(kbuf), &quot;%d\n&quot;, rotary_count);
    if (copy_to_user(buf, kbuf, len)) return -EFAULT;
    *pos += len; return len;
}
static ssize_t rotary_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) {
    long new_count; int ret; char kbuf[20];
    if (count &amp;gt;= sizeof(kbuf)) return -EINVAL;
    if (copy_from_user(kbuf, buf, count)) return -EFAULT;
    kbuf[count] = '\0';
    ret = kstrtol(kbuf, 10, &amp;amp;new_count);
    if (ret != 0) return ret;
    rotary_count = new_count; update_led_display(rotary_count);
    return count;
}
#define IOCTL_ROTARY_GET_COUNT _IOR('R', 1, int)
#define IOCTL_ROTARY_SET_COUNT _IOW('R', 2, int)
#define IOCTL_ROTARY_TOGGLE_LED5 _IO('R', 3)
#define IOCTL_ROTARY_GET_LED5_STATE _IOR('R', 4, int)
static long rotary_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    int ret = 0; int val;
    switch (cmd) {
        case IOCTL_ROTARY_GET_COUNT:
            val = rotary_count; if (copy_to_user((int __user *)arg, &amp;amp;val, sizeof(val))) ret = -EFAULT; break;
        case IOCTL_ROTARY_SET_COUNT:
            if (copy_from_user(&amp;amp;val, (int __user *)arg, sizeof(val))) { ret = -EFAULT; }
            else { rotary_count = val; update_led_display(rotary_count); } break;
        case IOCTL_ROTARY_TOGGLE_LED5: led5_state = !led5_state; gpio_set_value(LED5_GPIO, led5_state); break;
        case IOCTL_ROTARY_GET_LED5_STATE:
            val = led5_state; if (copy_to_user((int __user *)arg, &amp;amp;val, sizeof(val))) ret = -EFAULT; break;
        default: ret = -ENOTTY; break;
    }
    return ret;
}

// --- 모듈 초기화 함수 (MODIFIED) ---
static int __init rotary_init(void) {
    // ... (이전의 장치 등록, GPIO 요청 부분은 동일) ...
    int ret = 0;
    static const struct gpio leds[] = {
        { LED0_GPIO, GPIOF_OUT_INIT_LOW, &quot;led0&quot; }, { LED1_GPIO, GPIOF_OUT_INIT_LOW, &quot;led1&quot; },
        { LED2_GPIO, GPIOF_OUT_INIT_LOW, &quot;led2&quot; }, { LED3_GPIO, GPIOF_OUT_INIT_LOW, &quot;led3&quot; },
        { LED5_GPIO, GPIOF_OUT_INIT_LOW, &quot;led5&quot; }, { LED6_GPIO, GPIOF_OUT_INIT_LOW, &quot;led6&quot; },
        { LED7_GPIO, GPIOF_OUT_INIT_LOW, &quot;led7&quot; },
    };
    static const struct gpio inputs[] = {
        { ROTARY_CLK_GPIO, GPIOF_IN, &quot;r_clk&quot; }, { ROTARY_DT_GPIO,  GPIOF_IN, &quot;r_dt&quot;  },
        { KEY_SWITCH_GPIO, GPIOF_IN, &quot;r_sw&quot;  },
    };
    int i;

    ret = alloc_chrdev_region(&amp;amp;dev_num, 0, 1, DEVICE_NAME);
    if (ret &amp;lt; 0) return ret;
    cdev_init(&amp;amp;rotary_cdev, &amp;amp;rotary_fops);
    ret = cdev_add(&amp;amp;rotary_cdev, dev_num, 1);
    if (ret &amp;lt; 0) goto unregister_chrdev;
    rotary_class = class_create(DEVICE_NAME);
    if (IS_ERR(rotary_class)) { ret = PTR_ERR(rotary_class); goto cdev_del; }
    rotary_device = device_create(rotary_class, NULL, dev_num, NULL, DEVICE_NAME);
    if (IS_ERR(rotary_device)) { ret = PTR_ERR(rotary_device); goto class_destroy; }

    for (i = 0; i &amp;lt; ARRAY_SIZE(leds); i++) {
        ret = gpio_request_one(leds[i].gpio, leds[i].flags, leds[i].label);
        if (ret) { for (i--; i &amp;gt;= 0; i--) gpio_free(leds[i].gpio); goto device_destroy; }
    }
    for (i = 0; i &amp;lt; ARRAY_SIZE(inputs); i++) {
        ret = gpio_request_one(inputs[i].gpio, inputs[i].flags, inputs[i].label);
        if (ret) { for (i--; i &amp;gt;= 0; i--) gpio_free(inputs[i].gpio); goto free_led_gpios; }
    }
    update_led_display(0); last_rotary_clk_state = gpio_get_value(ROTARY_CLK_GPIO);

    // 디바운싱 타이머 초기화 (NEW)
    timer_setup(&amp;amp;debounce_timer, debounce_timer_callback, 0);

    // 인터럽트 등록 (이전과 동일)
    rotary_irq_clk = gpio_to_irq(ROTARY_CLK_GPIO);
    ret = request_irq(rotary_irq_clk, rotary_encoder_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, &quot;rotary_clk_irq&quot;, NULL);
    if (ret) goto free_input_gpios;

    key_switch_irq = gpio_to_irq(KEY_SWITCH_GPIO);
    ret = request_irq(key_switch_irq, key_switch_isr, IRQF_TRIGGER_FALLING, &quot;key_switch_irq&quot;, NULL);
    if (ret) goto free_rotary_irq;

    printk(KERN_INFO &quot;rotary_dev: Driver loaded with debounce timer. Major: %d\n&quot;, MAJOR(dev_num));
    return 0;

free_rotary_irq:
    free_irq(rotary_irq_clk, NULL);
free_input_gpios:
    for (i = 0; i &amp;lt; ARRAY_SIZE(inputs); i++) gpio_free(inputs[i].gpio);
free_led_gpios:
    for (i = 0; i &amp;lt; ARRAY_SIZE(leds); i++) gpio_free(leds[i].gpio);
device_destroy:
    device_destroy(rotary_class, dev_num);
class_destroy:
    class_destroy(rotary_class);
cdev_del:
    cdev_del(&amp;amp;rotary_cdev);
unregister_chrdev:
    unregister_chrdev_region(dev_num, 1);
    return ret;
}

// --- 모듈 종료 함수 (MODIFIED) ---
static void __exit rotary_exit(void) {
    int i;
    // 모듈이 제거될 때 타이머가 실행 중일 수 있으므로 안전하게 삭제
    del_timer_sync(&amp;amp;debounce_timer);

    free_irq(key_switch_irq, NULL);
    free_irq(rotary_irq_clk, NULL);

    static const struct gpio leds[] = { { LED0_GPIO }, { LED1_GPIO }, { LED2_GPIO }, { LED3_GPIO }, { LED5_GPIO }, { LED6_GPIO }, { LED7_GPIO }, };
    static const struct gpio inputs[] = { { ROTARY_CLK_GPIO }, { ROTARY_DT_GPIO }, { KEY_SWITCH_GPIO }, };
    for (i = 0; i &amp;lt; ARRAY_SIZE(inputs); i++) gpio_free(inputs[i].gpio);
    for (i = 0; i &amp;lt; ARRAY_SIZE(leds); i++) { gpio_set_value(leds[i].gpio, 0); gpio_free(leds[i].gpio); }

    device_destroy(rotary_class, dev_num);
    class_destroy(rotary_class);
    cdev_del(&amp;amp;rotary_cdev);
    unregister_chrdev_region(dev_num, 1);
    printk(KERN_INFO &quot;rotary_dev: Driver unloaded.\n&quot;);
}

module_init(rotary_init);
module_exit(rotary_exit);
MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;345&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgF3qH/btsPDFx4Hob/09Ha9glOkasKwZj8V1vj1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgF3qH/btsPDFx4Hob/09Ha9glOkasKwZj8V1vj1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgF3qH/btsPDFx4Hob/09Ha9glOkasKwZj8V1vj1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgF3qH%2FbtsPDFx4Hob%2F09Ha9glOkasKwZj8V1vj1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;345&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;345&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/GIZFrVPDJYc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/GIZFrVPDJYc&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github에 push하는 법&lt;/p&gt;
&lt;pre id=&quot;code_1753836381200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git add .

git commit -m &quot;new&quot;

git push origin main

혹시 push에서 pull을 해야하는 error가 발생한다면
git pull origin main --rebase&lt;/code&gt;&lt;/pre&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/544</guid>
      <comments>https://hotari.tistory.com/544#entry544comment</comments>
      <pubDate>Wed, 30 Jul 2025 09:43:40 +0900</pubDate>
    </item>
    <item>
      <title>18일차</title>
      <link>https://hotari.tistory.com/543</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.28&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rotary sw 디지털 회로 설계&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qgfDx/btsPCkggLCr/EYnGFPGJTEbkZKWmONWJM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qgfDx/btsPCkggLCr/EYnGFPGJTEbkZKWmONWJM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qgfDx/btsPCkggLCr/EYnGFPGJTEbkZKWmONWJM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqgfDx%2FbtsPCkggLCr%2FEYnGFPGJTEbkZKWmONWJM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;301&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmfP6o/btsPACin4wy/SGzfyfKBU0S7eDR4pHG8tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmfP6o/btsPACin4wy/SGzfyfKBU0S7eDR4pHG8tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmfP6o/btsPACin4wy/SGzfyfKBU0S7eDR4pHG8tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmfP6o%2FbtsPACin4wy%2FSGzfyfKBU0S7eDR4pHG8tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;303&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로터리 엔코더는 가전제품의 메뉴 선택이나 시간설정 등에 많이 사용되는 부품&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;건조기나 냉장고에서도 많이 사용.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p7Edg/btsPBLehNI8/8d0Q3ETfqdTX1cSnkBrMB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p7Edg/btsPBLehNI8/8d0Q3ETfqdTX1cSnkBrMB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p7Edg/btsPBLehNI8/8d0Q3ETfqdTX1cSnkBrMB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp7Edg%2FbtsPBLehNI8%2F8d0Q3ETfqdTX1cSnkBrMB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;159&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더란 기계적인 위치의 변화나 방향&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;middot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각도 등을 검출하여 전기적인 신호로 출력하는 센서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더의 명칭은 「&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;encode= &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;코드화 한다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;」가 유래이며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각도나 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;위치 변위의 코드화&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;즉 펄스 신호로 부호화 하는것&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;을 말한다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더 종류에는 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;회전의 각도나 방향을 검출하는 로터리 엔코더와 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;직선의 위치나 이동량을 검출하는 리니어 엔코더 등이 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전할 때 정해진 패턴의 신호를 출력하기 때문에 이 신호를 바탕으로 회전부가 얼마나 회전했는지를 파악할 수 있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전입력 하나로 다양한 입력을 받음으로써 부품의 수를 줄일 수 있기 때문에 로터리엔코더는 여러 제품의 입력장치로 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;광범위하게 활용되고 있음&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YX0u9/btsPADVUpMT/6L9TBJbGg1GHGn2W3PLPA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YX0u9/btsPADVUpMT/6L9TBJbGg1GHGn2W3PLPA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YX0u9/btsPADVUpMT/6L9TBJbGg1GHGn2W3PLPA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYX0u9%2FbtsPADVUpMT%2F6L9TBJbGg1GHGn2W3PLPA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;327&quot; height=&quot;291&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로터리 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전속도 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전량&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 및 회전 방향을 검출 하는 센서 장치&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자가 스위치를 돌리면&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스위치 내부의 접점들이 회전하며 특정 패턴으로 연결되고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 패턴 변화를 통해 각도 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변화를 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;감지&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전 방향과 각도 변화량을 펄스 형태로 출력하여 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;디지털 신호&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로 처리할 수 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있게&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clkmfb/btsPB6ickjT/Lk8nkDd2qLEooEGGE8MHzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clkmfb/btsPB6ickjT/Lk8nkDd2qLEooEGGE8MHzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clkmfb/btsPB6ickjT/Lk8nkDd2qLEooEGGE8MHzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fclkmfb%2FbtsPB6ickjT%2FLk8nkDd2qLEooEGGE8MHzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;184&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출력 펄스는 회전 위치의 절대치가 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아닌 회전한 각도에 의해 비례하는 펄스 출력&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2비트 상태 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이전 상태 &amp;rarr; 현재 상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 변화에 따라 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방향을 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;판단&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RXJVc/btsPB7nTGqG/JsF8bz8mVQPsNlFBDnnWO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RXJVc/btsPB7nTGqG/JsF8bz8mVQPsNlFBDnnWO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RXJVc/btsPB7nTGqG/JsF8bz8mVQPsNlFBDnnWO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRXJVc%2FbtsPB7nTGqG%2FJsF8bz8mVQPsNlFBDnnWO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;317&quot; height=&quot;197&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Ead2/btsPCKZ5t3g/HLmb8uI3GejPK92HMo4HN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Ead2/btsPCKZ5t3g/HLmb8uI3GejPK92HMo4HN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Ead2/btsPCKZ5t3g/HLmb8uI3GejPK92HMo4HN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Ead2%2FbtsPCKZ5t3g%2FHLmb8uI3GejPK92HMo4HN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;86&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;동작 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;원리&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(1) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전 감지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;EC11 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로터리 스위치는 회전축에 연결된 원판&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디스크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 규칙적인 패턴&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구멍 또는 틈&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 원판은 두 개의 광학 센서 또는 기계식 접점과 함께 작동&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(2)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호 생성&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;회전축이 회전하면&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;원판의 패턴이 광학 센서 또는 기계식 접점을 통과하면서 빛을 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차단하거나 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연결&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 차단&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연결 변화가 디지털 펄스 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;신호로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변환&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(3)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;펄스 신호 처리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;생성된 펄스 신호는 컨트롤러와 같은 장치에서 입력으로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;받아 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처리&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbVaJA/btsPBjbhxc0/VtqBEPtUAhbw2L5SeLi2hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbVaJA/btsPBjbhxc0/VtqBEPtUAhbw2L5SeLi2hK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbVaJA/btsPBjbhxc0/VtqBEPtUAhbw2L5SeLi2hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbVaJA%2FbtsPBjbhxc0%2FVtqBEPtUAhbw2L5SeLi2hK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;199&quot; height=&quot;158&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGYJwP/btsPCoXfG13/yxI1CKvAeQPTrCYQT5MpgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGYJwP/btsPCoXfG13/yxI1CKvAeQPTrCYQT5MpgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGYJwP/btsPCoXfG13/yxI1CKvAeQPTrCYQT5MpgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGYJwP%2FbtsPCoXfG13%2FyxI1CKvAeQPTrCYQT5MpgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;162&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cozRBU/btsPAKAwlRO/c0EPrLZiIfFmEELWnMaLTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cozRBU/btsPAKAwlRO/c0EPrLZiIfFmEELWnMaLTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cozRBU/btsPAKAwlRO/c0EPrLZiIfFmEELWnMaLTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcozRBU%2FbtsPAKAwlRO%2Fc0EPrLZiIfFmEELWnMaLTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;202&quot; height=&quot;146&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1Qo9n/btsPAjwMNDT/cDDQMPcTVxXhyxOsjQNe0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1Qo9n/btsPAjwMNDT/cDDQMPcTVxXhyxOsjQNe0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1Qo9n/btsPAjwMNDT/cDDQMPcTVxXhyxOsjQNe0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1Qo9n%2FbtsPAjwMNDT%2FcDDQMPcTVxXhyxOsjQNe0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;162&quot; height=&quot;119&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;EC11&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;은 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;증분형&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(Incremental) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로터리 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 한 종류&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;br /&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적인 가변 저항처럼 특정 각도 범위가 있는 것이 아니라&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;br /&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;360&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도 계속 회전할 수 있으며 회전 방향과 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전량을&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 감지하여 디지털 펄스 신호로 출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;br /&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, EC11 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;푸시 버튼 스위치&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가 내장되어 있어&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;노브를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 누르는 동작도 감지할 수 있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;증분형 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 회전 변위를 일련의 디지털 펄스 신호로 변환. &lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;절대적인 위치를 알려주는 것이 아니라, 얼마나 움직였고 어느 방향으로 움직였는지 알려&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;줌&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전원이 꺼지면 마지막 위치 정보는 유지되지 않&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;음&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A상&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(s&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Phase&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) 및 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(s2)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Phase&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) 출력:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; EC11 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 두 개의 출력(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A상&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B상&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)을 가&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;짐&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 두 신호는 서로 약 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;frac14;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 주기(90도)의 위상차를 가&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;짐&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시계 방향(CW) 회전 시:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A상이&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B상보다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 먼저 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HIGH로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 변&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반시계 방향(CCW) 회전 시:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B상이&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A상보다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 먼저 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HIGH로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 변&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 위상차를 분석하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 회전 방향을 감지할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;펄스 수:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;EC11은 보통 20펄스/회전 또는 24펄스/회전. 이 펄스 수를 세어 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회전량을&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 알 수 있다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;bull; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내장 푸시 버튼 (선택 사항):&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 많은 EC11 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;엔코더는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 축을 누르면 작동하는 스위치가 내장되어 있다. &lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 메뉴 선택, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;음소거&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 등의 기능을 구현하는 데 유용&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;block diagram&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1728&quot; data-origin-height=&quot;914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HyMcv/btsPBHbUcfR/QruJAwlprlJGEeIkC2g731/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HyMcv/btsPBHbUcfR/QruJAwlprlJGEeIkC2g731/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HyMcv/btsPBHbUcfR/QruJAwlprlJGEeIkC2g731/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHyMcv%2FbtsPBHbUcfR%2FQruJAwlprlJGEeIkC2g731%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1728&quot; height=&quot;914&quot; data-origin-width=&quot;1728&quot; data-origin-height=&quot;914&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rotary.v&lt;/p&gt;
&lt;pre id=&quot;code_1753673670402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module rotary(
    input clk,
    input reset,
    input clean_s1,
    input clean_s2,
    input clean_key,
    output [15:0] led
    );

    reg [1:0] r_prev_state = 2'b00;
    reg [1:0] r_curr_state = 2'b00;
    reg [1:0] r_direction = 2'b00;
    reg [7:0] r_count = 8'h00;

    reg [15:0] r_led = 16'b0;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            r_prev_state &amp;lt;= 2'b00;
            r_curr_state &amp;lt;= 2'b00;
            r_direction &amp;lt;= 2'b00;
            r_count &amp;lt;= 8'h00;
            r_led &amp;lt;= 16'b0;
        end else begin
            r_prev_state &amp;lt;= r_curr_state;
            r_curr_state &amp;lt;= {clean_s1, clean_s2};

            case ({r_prev_state, r_curr_state})

            4'b0010, 4'b1011, 4'b1101, 4'b0100: begin // CW 00 -&amp;gt; 10 -&amp;gt; 11 -&amp;gt; 01 -&amp;gt; 00
                if (r_count &amp;lt; 8'hFF) // overflow 방지
                    r_count &amp;lt;= r_count + 1;
                r_direction &amp;lt;= 2'b01;
            end

            4'b0001, 4'b0111, 4'b1110, 4'b1000: begin // CCW 00 -&amp;gt; 01 -&amp;gt; 11 -&amp;gt; 10 -&amp;gt; 00
                if (r_count &amp;gt; 8'h00) // underflow 방지
                    r_count &amp;lt;= r_count - 1;
                r_direction &amp;lt;= 2'b10;
            end

            endcase

            // clean_key ON/OFF 제어
            r_led[13] &amp;lt;= ~clean_key;

            // LED 출력 구성
            r_led[15:14] &amp;lt;= r_direction;
            r_led[12:8]  &amp;lt;= 5'b0;
            r_led[7:0]   &amp;lt;= r_count;

        end
    end

    assign led = r_led;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;top.v&lt;/p&gt;
&lt;pre id=&quot;code_1753673692884&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module top(
    input clk,
    input reset,  // btnU
    input [2:0] btn,
    input [7:0] sw,
    input RsRx,
    input s1, // JC1
    input s2, // JC2
    input key, // JC3
    output RsTx,
    output [7:0] seg,
    output [3:0] an,
    output [15:0] led
    );

    wire [2:0] w_btn_debounce;
    wire [13:0] w_seg_data;
    wire w_tick;
    wire [7:0] w_rx_data;
    wire w_rx_done;

    // 디바운싱 된 입력
    wire w_clean_s1, w_clean_s2, w_clean_key;

    button_debounce u_button_debounce(
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(btn[0]),
        .o_btn_clean(w_btn_debounce)
    );

    button_debounce #(.DEBOUNCE_LIMIT(200_000))u_s1_debounce( // debounce 2ms
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(s1),
        .o_btn_clean(w_clean_s1)
    );

    button_debounce #(.DEBOUNCE_LIMIT(200_000))u_s2_debounce( // debounce 2ms
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(s2),
        .o_btn_clean(w_clean_s2)
    );

    button_debounce #(.DEBOUNCE_LIMIT(200_000))u_key_debounce( // debounce 2ms
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(key),
        .o_btn_clean(w_clean_key)
    );

    rotary u_rotary(
        .clk(clk),
        .reset(reset),
        .clean_s1(w_clean_s1),
        .clean_s2(w_clean_s2),
        .clean_key(w_clean_key),
        .led(led)
    );

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Basys3-Master_original.xdc&lt;/p&gt;
&lt;pre id=&quot;code_1753673712355&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;## This file is a general .xdc for the Basys3 rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project

## Clock signal
set_property -dict { PACKAGE_PIN W5   IOSTANDARD LVCMOS33 } [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]


## Switches
set_property -dict { PACKAGE_PIN V17   IOSTANDARD LVCMOS33 } [get_ports {sw[0]}]
set_property -dict { PACKAGE_PIN V16   IOSTANDARD LVCMOS33 } [get_ports {sw[1]}]
set_property -dict { PACKAGE_PIN W16   IOSTANDARD LVCMOS33 } [get_ports {sw[2]}]
set_property -dict { PACKAGE_PIN W17   IOSTANDARD LVCMOS33 } [get_ports {sw[3]}]
set_property -dict { PACKAGE_PIN W15   IOSTANDARD LVCMOS33 } [get_ports {sw[4]}]
set_property -dict { PACKAGE_PIN V15   IOSTANDARD LVCMOS33 } [get_ports {sw[5]}]
set_property -dict { PACKAGE_PIN W14   IOSTANDARD LVCMOS33 } [get_ports {sw[6]}]
set_property -dict { PACKAGE_PIN W13   IOSTANDARD LVCMOS33 } [get_ports {sw[7]}]
#set_property -dict { PACKAGE_PIN V2    IOSTANDARD LVCMOS33 } [get_ports {sw[8]}]
#set_property -dict { PACKAGE_PIN T3    IOSTANDARD LVCMOS33 } [get_ports {sw[9]}]
#set_property -dict { PACKAGE_PIN T2    IOSTANDARD LVCMOS33 } [get_ports {sw[10]}]
#set_property -dict { PACKAGE_PIN R3    IOSTANDARD LVCMOS33 } [get_ports {sw[11]}]
#set_property -dict { PACKAGE_PIN W2    IOSTANDARD LVCMOS33 } [get_ports {sw[12]}]
#set_property -dict { PACKAGE_PIN U1    IOSTANDARD LVCMOS33 } [get_ports {sw[13]}]
#set_property -dict { PACKAGE_PIN T1    IOSTANDARD LVCMOS33 } [get_ports {sw[14]}]
#set_property -dict { PACKAGE_PIN R2    IOSTANDARD LVCMOS33 } [get_ports { cin }]


## LEDs
set_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS33 } [get_ports {led[0]}]
set_property -dict { PACKAGE_PIN E19   IOSTANDARD LVCMOS33 } [get_ports {led[1]}]
set_property -dict { PACKAGE_PIN U19   IOSTANDARD LVCMOS33 } [get_ports {led[2]}]
set_property -dict { PACKAGE_PIN V19   IOSTANDARD LVCMOS33 } [get_ports {led[3]}]
set_property -dict { PACKAGE_PIN W18   IOSTANDARD LVCMOS33 } [get_ports {led[4]}]
set_property -dict { PACKAGE_PIN U15   IOSTANDARD LVCMOS33 } [get_ports {led[5]}]
set_property -dict { PACKAGE_PIN U14   IOSTANDARD LVCMOS33 } [get_ports {led[6]}]
set_property -dict { PACKAGE_PIN V14   IOSTANDARD LVCMOS33 } [get_ports {led[7]}]
set_property -dict { PACKAGE_PIN V13   IOSTANDARD LVCMOS33 } [get_ports {led[8]}]
set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports {led[9]}]
set_property -dict { PACKAGE_PIN W3    IOSTANDARD LVCMOS33 } [get_ports {led[10]}]
set_property -dict { PACKAGE_PIN U3    IOSTANDARD LVCMOS33 } [get_ports {led[11]}]
set_property -dict { PACKAGE_PIN P3    IOSTANDARD LVCMOS33 } [get_ports {led[12]}]
set_property -dict { PACKAGE_PIN N3    IOSTANDARD LVCMOS33 } [get_ports {led[13]}]
set_property -dict { PACKAGE_PIN P1    IOSTANDARD LVCMOS33 } [get_ports {led[14]}]
set_property -dict { PACKAGE_PIN L1    IOSTANDARD LVCMOS33 } [get_ports {led[15]}]


##7 Segment Display
set_property -dict { PACKAGE_PIN W7   IOSTANDARD LVCMOS33 } [get_ports {seg[0]}]
set_property -dict { PACKAGE_PIN W6   IOSTANDARD LVCMOS33 } [get_ports {seg[1]}]
set_property -dict { PACKAGE_PIN U8   IOSTANDARD LVCMOS33 } [get_ports {seg[2]}]
set_property -dict { PACKAGE_PIN V8   IOSTANDARD LVCMOS33 } [get_ports {seg[3]}]
set_property -dict { PACKAGE_PIN U5   IOSTANDARD LVCMOS33 } [get_ports {seg[4]}]
set_property -dict { PACKAGE_PIN V5   IOSTANDARD LVCMOS33 } [get_ports {seg[5]}]
set_property -dict { PACKAGE_PIN U7   IOSTANDARD LVCMOS33 } [get_ports {seg[6]}]
set_property -dict { PACKAGE_PIN V7   IOSTANDARD LVCMOS33 } [get_ports {seg[7]}]  
# seg[7] : dp 
set_property -dict { PACKAGE_PIN U2   IOSTANDARD LVCMOS33 } [get_ports {an[0]}]
set_property -dict { PACKAGE_PIN U4   IOSTANDARD LVCMOS33 } [get_ports {an[1]}]
set_property -dict { PACKAGE_PIN V4   IOSTANDARD LVCMOS33 } [get_ports {an[2]}]
set_property -dict { PACKAGE_PIN W4   IOSTANDARD LVCMOS33 } [get_ports {an[3]}]


##Buttons
set_property -dict { PACKAGE_PIN T18   IOSTANDARD LVCMOS33 } [get_ports reset]
set_property -dict { PACKAGE_PIN W19   IOSTANDARD LVCMOS33 } [get_ports {btn[0]}]
set_property -dict { PACKAGE_PIN U18   IOSTANDARD LVCMOS33 } [get_ports {btn[1]}]
set_property -dict { PACKAGE_PIN T17   IOSTANDARD LVCMOS33 } [get_ports {btn[2]}]
#set_property -dict { PACKAGE_PIN U17   IOSTANDARD LVCMOS33 } [get_ports btnD]


##Pmod Header JA
#set_property -dict { PACKAGE_PIN J1   IOSTANDARD LVCMOS33 } [get_ports {JA[0]}];#Sch name = JA1
#set_property -dict { PACKAGE_PIN L2   IOSTANDARD LVCMOS33 } [get_ports {JA[1]}];#Sch name = JA2
#set_property -dict { PACKAGE_PIN J2   IOSTANDARD LVCMOS33 } [get_ports {JA[2]}];#Sch name = JA3
#set_property -dict { PACKAGE_PIN G2   IOSTANDARD LVCMOS33 } [get_ports {JA[3]}];#Sch name = JA4
#set_property -dict { PACKAGE_PIN H1   IOSTANDARD LVCMOS33 } [get_ports {JA[4]}];#Sch name = JA7
#set_property -dict { PACKAGE_PIN K2   IOSTANDARD LVCMOS33 } [get_ports {JA[5]}];#Sch name = JA8
#set_property -dict { PACKAGE_PIN H2   IOSTANDARD LVCMOS33 } [get_ports {JA[6]}];#Sch name = JA9
#set_property -dict { PACKAGE_PIN G3   IOSTANDARD LVCMOS33 } [get_ports {JA[7]}];#Sch name = JA10

##Pmod Header JB
#set_property -dict { PACKAGE_PIN A14   IOSTANDARD LVCMOS33 } [get_ports {JB[0]}];#Sch name = JB1
#set_property -dict { PACKAGE_PIN A16   IOSTANDARD LVCMOS33 } [get_ports {JB[1]}];#Sch name = JB2
#set_property -dict { PACKAGE_PIN B15   IOSTANDARD LVCMOS33 } [get_ports {JB[2]}];#Sch name = JB3
#set_property -dict { PACKAGE_PIN B16   IOSTANDARD LVCMOS33 } [get_ports {JB[3]}];#Sch name = JB4
#set_property -dict { PACKAGE_PIN A15   IOSTANDARD LVCMOS33 } [get_ports {JB[4]}];#Sch name = JB7
#set_property -dict { PACKAGE_PIN A17   IOSTANDARD LVCMOS33 } [get_ports {JB[5]}];#Sch name = JB8
#set_property -dict { PACKAGE_PIN C15   IOSTANDARD LVCMOS33 } [get_ports {JB[6]}];#Sch name = JB9
#set_property -dict { PACKAGE_PIN C16   IOSTANDARD LVCMOS33 } [get_ports {JB[7]}];#Sch name = JB10

##Pmod Header JC
set_property -dict { PACKAGE_PIN K17   IOSTANDARD LVCMOS33 } [get_ports { s1 }];#Sch name = JC1
set_property -dict { PACKAGE_PIN M18   IOSTANDARD LVCMOS33 } [get_ports { s2 }];#Sch name = JC2
set_property -dict { PACKAGE_PIN N17   IOSTANDARD LVCMOS33 } [get_ports { key }];#Sch name = JC3
#set_property -dict { PACKAGE_PIN P18   IOSTANDARD LVCMOS33 } [get_ports {JC[3]}];#Sch name = JC4
#set_property -dict { PACKAGE_PIN L17   IOSTANDARD LVCMOS33 } [get_ports {JC[4]}];#Sch name = JC7
#set_property -dict { PACKAGE_PIN M19   IOSTANDARD LVCMOS33 } [get_ports {JC[5]}];#Sch name = JC8
#set_property -dict { PACKAGE_PIN P17   IOSTANDARD LVCMOS33 } [get_ports {JC[6]}];#Sch name = JC9
#set_property -dict { PACKAGE_PIN R18   IOSTANDARD LVCMOS33 } [get_ports {JC[7]}];#Sch name = JC10

##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN J3   IOSTANDARD LVCMOS33 } [get_ports {JXADC[0]}];#Sch name = XA1_P
#set_property -dict { PACKAGE_PIN L3   IOSTANDARD LVCMOS33 } [get_ports {JXADC[1]}];#Sch name = XA2_P
#set_property -dict { PACKAGE_PIN M2   IOSTANDARD LVCMOS33 } [get_ports {JXADC[2]}];#Sch name = XA3_P
#set_property -dict { PACKAGE_PIN N2   IOSTANDARD LVCMOS33 } [get_ports {JXADC[3]}];#Sch name = XA4_P
#set_property -dict { PACKAGE_PIN K3   IOSTANDARD LVCMOS33 } [get_ports {JXADC[4]}];#Sch name = XA1_N
#set_property -dict { PACKAGE_PIN M3   IOSTANDARD LVCMOS33 } [get_ports {JXADC[5]}];#Sch name = XA2_N
#set_property -dict { PACKAGE_PIN M1   IOSTANDARD LVCMOS33 } [get_ports {JXADC[6]}];#Sch name = XA3_N
#set_property -dict { PACKAGE_PIN N1   IOSTANDARD LVCMOS33 } [get_ports {JXADC[7]}];#Sch name = XA4_N


##VGA Connector
#set_property -dict { PACKAGE_PIN G19   IOSTANDARD LVCMOS33 } [get_ports {vgaRed[0]}]
#set_property -dict { PACKAGE_PIN H19   IOSTANDARD LVCMOS33 } [get_ports {vgaRed[1]}]
#set_property -dict { PACKAGE_PIN J19   IOSTANDARD LVCMOS33 } [get_ports {vgaRed[2]}]
#set_property -dict { PACKAGE_PIN N19   IOSTANDARD LVCMOS33 } [get_ports {vgaRed[3]}]
#set_property -dict { PACKAGE_PIN N18   IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[0]}]
#set_property -dict { PACKAGE_PIN L18   IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[1]}]
#set_property -dict { PACKAGE_PIN K18   IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[2]}]
#set_property -dict { PACKAGE_PIN J18   IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[3]}]
#set_property -dict { PACKAGE_PIN J17   IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[0]}]
#set_property -dict { PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[1]}]
#set_property -dict { PACKAGE_PIN G17   IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[2]}]
#set_property -dict { PACKAGE_PIN D17   IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[3]}]
#set_property -dict { PACKAGE_PIN P19   IOSTANDARD LVCMOS33 } [get_ports Hsync]
#set_property -dict { PACKAGE_PIN R19   IOSTANDARD LVCMOS33 } [get_ports Vsync]


##USB-RS232 Interface
set_property -dict { PACKAGE_PIN B18   IOSTANDARD LVCMOS33 } [get_ports RsRx]
set_property -dict { PACKAGE_PIN A18   IOSTANDARD LVCMOS33 } [get_ports RsTx]


##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33   PULLUP true } [get_ports PS2Clk]
#set_property -dict { PACKAGE_PIN B17   IOSTANDARD LVCMOS33   PULLUP true } [get_ports PS2Data]


##Quad SPI Flash
##Note that CCLK_0 cannot be placed in 7 series devices. You can access it using the
##STARTUPE2 primitive.
#set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports {QspiDB[0]}]
#set_property -dict { PACKAGE_PIN D19   IOSTANDARD LVCMOS33 } [get_ports {QspiDB[1]}]
#set_property -dict { PACKAGE_PIN G18   IOSTANDARD LVCMOS33 } [get_ports {QspiDB[2]}]
#set_property -dict { PACKAGE_PIN F18   IOSTANDARD LVCMOS33 } [get_ports {QspiDB[3]}]
#set_property -dict { PACKAGE_PIN K19   IOSTANDARD LVCMOS33 } [get_ports QspiCSn]


## Configuration options, can be used for all designs
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]

## SPI configuration mode options for QSPI boot, can be used for all designs
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/543</guid>
      <comments>https://hotari.tistory.com/543#entry543comment</comments>
      <pubDate>Mon, 28 Jul 2025 17:00:49 +0900</pubDate>
    </item>
    <item>
      <title>14 ~ 17일차 mini Project4 - 공기 조화 설비 HVAC_System</title>
      <link>https://hotari.tistory.com/542</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.17 ~ 2025.07.22&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;811&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKdxm9/btsPrsAv6kL/QUvhItdkTrmOEihAwfGBM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKdxm9/btsPrsAv6kL/QUvhItdkTrmOEihAwfGBM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKdxm9/btsPrsAv6kL/QUvhItdkTrmOEihAwfGBM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKdxm9%2FbtsPrsAv6kL%2FQUvhItdkTrmOEihAwfGBM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;272&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;811&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;  BESPOKE 스마트 가전 FPGA 시스템&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 센서 및 액추에이터를 통합하여 구현한 스마트 가전 시뮬레이션 FPGA 프로젝트&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  프로젝트 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 Vivado 기반 Basys3 보드에서 다음과 같은 스마트 가전 기능을 통합적으로 구현합니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초음파 거리 측정&lt;/li&gt;
&lt;li&gt;DHT11 온습도 센서 기반 HVAC 제어&lt;/li&gt;
&lt;li&gt;전자레인지 기능 (타이머, 서보 제어, 부저 알림)&lt;/li&gt;
&lt;li&gt;UART 통신을 통한 측정값 전송 및 외부 명령 수신&lt;/li&gt;
&lt;li&gt;스톱워치 / IDLE 애니메이션&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  주요 기능&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모드 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MODE 0 (Idle)&lt;/td&gt;
&lt;td&gt;FND 순환 애니메이션 표시 (대기 상태)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MODE 1 (공조기 자동)&lt;/td&gt;
&lt;td&gt;온습도 + 초음파 거리 측정 &amp;rarr; 자동 모터 제어 (측정 온도 기준 PWM) + UART 전송&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MODE 2 (공조기 수동)&lt;/td&gt;
&lt;td&gt;온습도 측정 + 스위치&amp;middot;버튼으로 설정한 희망 온도에 따라 DC 모터 제어 + UART 전송&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MODE 3 (전자레인지)&lt;/td&gt;
&lt;td&gt;시간 설정 + 조리 동작 FSM + 서보모터 제어 + 종료시 부저 알림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MODE 4 (스톱워치)&lt;/td&gt;
&lt;td&gt;실시간 스톱워치 카운트 FND 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  UART 포맷 명세&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 종류 포맷 예시 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;초음파 거리&lt;/td&gt;
&lt;td&gt;Dist:0123cm&lt;/td&gt;
&lt;td&gt;거리 측정 결과 (cm)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;온도/습도&lt;/td&gt;
&lt;td&gt;Temp:27.06C Humi:64.00%&lt;/td&gt;
&lt;td&gt;정수 2자리 + 소수 2자리로 전송&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;오류 메시지&lt;/td&gt;
&lt;td&gt;Error: DHT fail&lt;/td&gt;
&lt;td&gt;DHT11 측정 실패 시 전송 (예정 기능)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚙️ 사용한 주요 모듈&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;센서 및 제어&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;hcsr04.v: 초음파 거리 측정&lt;/li&gt;
&lt;li&gt;dht11_controller.v: 온습도 센서 제어 FSM&lt;/li&gt;
&lt;li&gt;manual_temp_controller.v: 수동 온도 설정 FSM&lt;/li&gt;
&lt;li&gt;hvac_pwm_dcmotor.v: 온도 기반 DC 모터 제어&lt;/li&gt;
&lt;li&gt;mw_controller.v, mw_servo_motor.v: 전자레인지 FSM&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;디스플레이 및 출력&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fnd_controller.v: 7-segment 표시 제어&lt;/li&gt;
&lt;li&gt;idle_fnd.v: IDLE 모드 애니메이션&lt;/li&gt;
&lt;li&gt;buzzer_controller.v: 부저 제어&lt;/li&gt;
&lt;li&gt;uart_tx.v, data_sender.v: UART 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;공통 모듈&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;button_debounce.v: 버튼 디바운싱&lt;/li&gt;
&lt;li&gt;tick_generator.v: 1Hz / 1us 등 클럭 분주기&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  FSM 다이어그램 요약 (Mermaid)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  DHT11 FSM&lt;/h3&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; IDLE
    IDLE --&amp;gt; SEND_REQUEST: after 3s
    SEND_REQUEST --&amp;gt; WAIT_RESPONSE_LOW: after 18ms
    WAIT_RESPONSE_LOW --&amp;gt; WAIT_RESPONSE_HIGH: falling edge detected
    WAIT_RESPONSE_HIGH --&amp;gt; READ_DATA: rising edge detected
    READ_DATA --&amp;gt; VERIFY_CHECKSUM: 40bit done
    VERIFY_CHECKSUM --&amp;gt; IDLE

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; &amp;zwj;♂️ 초음파 FSM&lt;/h3&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; WAIT
    WAIT --&amp;gt; TRIGGER: tick_1Hz
    TRIGGER --&amp;gt; WAIT_ECHO: 10us pulse sent
    WAIT_ECHO --&amp;gt; MEASURE: echo rising edge
    MEASURE --&amp;gt; DONE: echo falling edge
    DONE --&amp;gt; WAIT: latch value, wait for next tick

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ 공조기 FSM (HVAC 제어)&lt;/h3&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; IDLE
    IDLE --&amp;gt; AUTO_CONTROL: btnL (mode change)
    AUTO_CONTROL --&amp;gt; READ_DISTANCE: tick_1Hz
    AUTO_CONTROL --&amp;gt; READ_TEMPERATURE: tick_1Hz
    READ_DISTANCE --&amp;gt; DISABLE_MOTOR: distance &amp;lt;= 5cm
    READ_DISTANCE --&amp;gt; SET_PWM: distance &amp;gt; 5cm
    READ_TEMPERATURE --&amp;gt; EVALUATE_TEMP
    EVALUATE_TEMP --&amp;gt; MANUAL_CONTROL: btnL (mode change)
    MANUAL_CONTROL --&amp;gt; APPLY_TARGET_TEMP: sw[1] == 1 / btnU(Temp&amp;uarr;), btnD(Temp&amp;darr;)
    APPLY_TARGET_TEMP --&amp;gt; SET_PWM: 희망 온도 기준 제어
    EVALUATE_TEMP --&amp;gt; SET_PWM: 측정된 온도 기준 자동 제어
    DISABLE_MOTOR --&amp;gt; SET_PWM

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  전자레인지 FSM&lt;/h3&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; IDLE
    IDLE --&amp;gt; SET_TIME: btn_inc/dec
    SET_TIME --&amp;gt; COOKING: btn_start
    COOKING --&amp;gt; COMPLETE: time = 0
    COMPLETE --&amp;gt; DOOR_OPEN: btn_open
    DOOR_OPEN --&amp;gt; DOOR_CLOSE: btn_close
    DOOR_CLOSE --&amp;gt; IDLE

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⏱ 분초시계 / 스톱워치 FSM&lt;/h3&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; IDLE
    IDLE --&amp;gt; IDLE: btnD (circle speed control)
    IDLE --&amp;gt; MINSEC_WATCH: btnR
    MINSEC_WATCH --&amp;gt; STOPWATCH: btnR
    STOPWATCH --&amp;gt; IDLE: btnR
    STOPWATCH --&amp;gt; STOPWATCH: btnC (pause / resume)
    STOPWATCH --&amp;gt; STOPWATCH: tick_1Hz (count up)
    STOPWATCH --&amp;gt; STOPWATCH: btnU (reset time)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  상세 구현 기능 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;압축파일 내 Verilog 소스 기준으로 구현된 각 기능은 다음과 같습니다:&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 센서 및 입력 처리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hcsr04.v&lt;/td&gt;
&lt;td&gt;HC-SR04 초음파 센서 구동 및 거리 측정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dht11.v / dht11_controller.v&lt;/td&gt;
&lt;td&gt;DHT11 온습도 센서 통신 FSM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;manual_temp_controller.v&lt;/td&gt;
&lt;td&gt;스위치 기반 수동 온도 설정 FSM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;button_debounce.v&lt;/td&gt;
&lt;td&gt;버튼 디바운싱 회로 구현 (노이즈 방지)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ DC 모터 / HVAC 제어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hvac_pwm_dcmotor.v&lt;/td&gt;
&lt;td&gt;자동/수동 온도에 따라 DC 모터 PWM 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pwm_dcmotor.v, pwm_duty_cycle_control.v&lt;/td&gt;
&lt;td&gt;일반 DC 모터 제어용 PWM 회로&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 전자레인지 시스템&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;microwave.v&lt;/td&gt;
&lt;td&gt;전체 전자레인지 시스템 통합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mw_controller.v, mw_fsm_controller.v&lt;/td&gt;
&lt;td&gt;조리 상태 FSM 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mw_servo_motor.v&lt;/td&gt;
&lt;td&gt;서보 모터로 문 여닫기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mw_time_controller.v&lt;/td&gt;
&lt;td&gt;조리 시간 설정 및 카운트&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 디스플레이 및 시각 출력&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fnd_controller.v, fnd_controller_2.v&lt;/td&gt;
&lt;td&gt;7-세그먼트 디스플레이 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;idle_fnd.v&lt;/td&gt;
&lt;td&gt;IDLE 모드 애니메이션 출력&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sw_fnd_controller.v, dht11_fnd_controller.v&lt;/td&gt;
&lt;td&gt;스톱워치 및 온습도 값 디스플레이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 스톱워치 / 타이머&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;minsec_stopwatch.v&lt;/td&gt;
&lt;td&gt;분/초 단위 스톱워치 카운트 FSM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sw_controller.v&lt;/td&gt;
&lt;td&gt;스톱워치 모드 전환 및 동작 FSM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 부저 제어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;buzzer_top.v&lt;/td&gt;
&lt;td&gt;전체 부저 시스템 통합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;power_on_buzzer.v, open_buzzer.v&lt;/td&gt;
&lt;td&gt;버튼 기반 부저 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ultra_buzzer_controller.v&lt;/td&gt;
&lt;td&gt;거리 경보용 부저 제어 FSM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ UART 통신&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명 기능 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;uart_tx.v, uart_rx.v&lt;/td&gt;
&lt;td&gt;송수신 회로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uart_controller.v&lt;/td&gt;
&lt;td&gt;전체 UART 통신 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;data_sender.v, dht11_data_sender.v&lt;/td&gt;
&lt;td&gt;UART 전송 포맷 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ 시연 영상&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 종류 링크&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;  전체 동작 영상&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://youtube.com/shorts/1sJZ1K1JNUI&quot;&gt;동작 영상 보러가기&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;  UART 통신 영상&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://youtube.com/shorts/0ijM9RrLEJM&quot;&gt;comportmaster 출력 영상&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  사용법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Vivado로 프로젝트 열기 (15.BESPOKE.xpr)&lt;/li&gt;
&lt;li&gt;Top Module: top&lt;/li&gt;
&lt;li&gt;bitstream 생성 후 Basys3에 다운로드&lt;/li&gt;
&lt;li&gt;스위치/버튼 조작 및 comportmaster로 UART 결과 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  배선 및 Basys3 핀 할당 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능 핀 이름 연결 포트명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;메인 클럭&lt;/td&gt;
&lt;td&gt;W5&lt;/td&gt;
&lt;td&gt;clk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;리셋 버튼&lt;/td&gt;
&lt;td&gt;R2&lt;/td&gt;
&lt;td&gt;reset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스위치&lt;/td&gt;
&lt;td&gt;V17 \~ R2&lt;/td&gt;
&lt;td&gt;sw[0] ~ sw[14]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;버튼&lt;/td&gt;
&lt;td&gt;W19, U18, T17, T18, U17&lt;/td&gt;
&lt;td&gt;btn[0] ~ btn[4]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LED&lt;/td&gt;
&lt;td&gt;U16 \~ L1&lt;/td&gt;
&lt;td&gt;led[0] ~ led[15]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7세그먼트&lt;/td&gt;
&lt;td&gt;W7 \~ V7&lt;/td&gt;
&lt;td&gt;seg[0] ~ seg[7]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anode&lt;/td&gt;
&lt;td&gt;U2, U4, V4, W4&lt;/td&gt;
&lt;td&gt;an[0] ~ an[3]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;초음파 센서&lt;/td&gt;
&lt;td&gt;B15, B16&lt;/td&gt;
&lt;td&gt;echo, trig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DHT11 데이터&lt;/td&gt;
&lt;td&gt;R18&lt;/td&gt;
&lt;td&gt;dht11_data (pull-up 적용)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;부저&lt;/td&gt;
&lt;td&gt;K17&lt;/td&gt;
&lt;td&gt;buzzer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DC 모터 제어&lt;/td&gt;
&lt;td&gt;JA1\~JA3&lt;/td&gt;
&lt;td&gt;PWM_OUT, in1_in2[0], in1_in2[1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서보모터&lt;/td&gt;
&lt;td&gt;JA4&lt;/td&gt;
&lt;td&gt;PWM_SERVO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HVAC DC 모터 제어&lt;/td&gt;
&lt;td&gt;J3, L3, M2&lt;/td&gt;
&lt;td&gt;PWM_OUT_HVAC, in1_in2_HVAC[0], in1_in2_HVAC[1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UART 통신&lt;/td&gt;
&lt;td&gt;A18, B18&lt;/td&gt;
&lt;td&gt;RsTx, RsRx&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  개발 환경&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Vivado 2021.1&lt;/li&gt;
&lt;li&gt;Basys3 FPGA 보드&lt;/li&gt;
&lt;li&gt;comportmaster 또는 Tera Term&lt;/li&gt;
&lt;li&gt;100MHz 시스템 클럭 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✍️ 참고 및 기여&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 임베디드 시스템, 센서 통합, 하드웨어 제어, UART 통신 등 실전 회로 설계 능력을 종합적으로 훈련하기 위해 설계되었습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/542</guid>
      <comments>https://hotari.tistory.com/542#entry542comment</comments>
      <pubDate>Tue, 22 Jul 2025 11:10:07 +0900</pubDate>
    </item>
    <item>
      <title>13일차</title>
      <link>https://hotari.tistory.com/541</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.16&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART 통신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ASCII '0' ~ '9' 1초 단위로 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'PSH' 이름 1초 단위로 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART_RX&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2669&quot; data-origin-height=&quot;1400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OrwzQ/btsPkHjJyWA/DBsWgz4PbTRs0ROQ1kWiFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OrwzQ/btsPkHjJyWA/DBsWgz4PbTRs0ROQ1kWiFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OrwzQ/btsPkHjJyWA/DBsWgz4PbTRs0ROQ1kWiFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOrwzQ%2FbtsPkHjJyWA%2FDBsWgz4PbTRs0ROQ1kWiFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;313&quot; data-origin-width=&quot;2669&quot; data-origin-height=&quot;1400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1733&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GycAQ/btsPktszZnT/6TPYRw0ZwMHaABkxMksV61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GycAQ/btsPktszZnT/6TPYRw0ZwMHaABkxMksV61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GycAQ/btsPktszZnT/6TPYRw0ZwMHaABkxMksV61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGycAQ%2FbtsPktszZnT%2F6TPYRw0ZwMHaABkxMksV61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1733&quot; height=&quot;766&quot; data-origin-width=&quot;1733&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1907&quot; data-origin-height=&quot;980&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diXKlo/btsPkuZfvsf/fSlF9R84F619pduZafy07k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diXKlo/btsPkuZfvsf/fSlF9R84F619pduZafy07k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diXKlo/btsPkuZfvsf/fSlF9R84F619pduZafy07k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiXKlo%2FbtsPkuZfvsf%2FfSlF9R84F619pduZafy07k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1907&quot; height=&quot;980&quot; data-origin-width=&quot;1907&quot; data-origin-height=&quot;980&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/77.uart&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/77.uart&lt;/a&gt;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/541</guid>
      <comments>https://hotari.tistory.com/541#entry541comment</comments>
      <pubDate>Wed, 16 Jul 2025 17:06:22 +0900</pubDate>
    </item>
    <item>
      <title>12일차</title>
      <link>https://hotari.tistory.com/540</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.15&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART(Universal&amp;nbsp;Asynchronous&amp;nbsp;Receiver/Transmitter) &lt;br /&gt;비동기&amp;nbsp;직렬&amp;nbsp;통신&amp;nbsp;방식으로,&amp;nbsp;마이크로컨트롤러(MCU),&amp;nbsp;FPGA,&amp;nbsp;센서&amp;nbsp;등에서&amp;nbsp;널리&amp;nbsp;사용되는&amp;nbsp;통신&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;■&amp;nbsp;UART&amp;nbsp;통신의&amp;nbsp;특징 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;비동기식(Asynchronous):&amp;nbsp;클럭&amp;nbsp;신호를&amp;nbsp;별도로&amp;nbsp;사용하지&amp;nbsp;않음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;직렬&amp;nbsp;통신:&amp;nbsp;데이터를&amp;nbsp;한&amp;nbsp;비트씩&amp;nbsp;순차적으로&amp;nbsp;전송 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Full-Duplex&amp;nbsp;가능:&amp;nbsp;송신(TX)과&amp;nbsp;수신(RX)을&amp;nbsp;동시에&amp;nbsp;처리&amp;nbsp;가능 &lt;br /&gt;&lt;br /&gt;■&amp;nbsp;UART&amp;nbsp;데이터&amp;nbsp;통신&amp;nbsp;규격 &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nt4s6/btsPi3TIg2I/oFFKRqW0nYhsrDpiepFgEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nt4s6/btsPi3TIg2I/oFFKRqW0nYhsrDpiepFgEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nt4s6/btsPi3TIg2I/oFFKRqW0nYhsrDpiepFgEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnt4s6%2FbtsPi3TIg2I%2FoFFKRqW0nYhsrDpiepFgEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;398&quot; height=&quot;88&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;327&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작&amp;nbsp;(START)&amp;nbsp;비트:&amp;nbsp;통신의&amp;nbsp;시작을&amp;nbsp;의미하며&amp;nbsp;한&amp;nbsp;비트&amp;nbsp;시간&amp;nbsp;길이만큼&amp;nbsp;0을&amp;nbsp;유지한다.&amp;nbsp; &lt;br /&gt;데이터&amp;nbsp;비트:&amp;nbsp;5~8비트의&amp;nbsp;데이터&amp;nbsp;전송을&amp;nbsp;한다.&amp;nbsp; &lt;br /&gt;패리티&amp;nbsp;(PARITY)&amp;nbsp;비트:&amp;nbsp;오류&amp;nbsp;검증을&amp;nbsp;하기&amp;nbsp;위한&amp;nbsp;패리티&amp;nbsp;값을&amp;nbsp;생성하여&amp;nbsp;송신하고&amp;nbsp;수신쪽에서&amp;nbsp;오류&amp;nbsp;판단한다.&amp;nbsp; &lt;br /&gt;끝&amp;nbsp;(STOP)&amp;nbsp;비트:&amp;nbsp;통신&amp;nbsp;종료를&amp;nbsp;알린다.&amp;nbsp; &lt;br /&gt;보드레이트&amp;nbsp;(Baud&amp;nbsp;Rate):&amp;nbsp;Baud&amp;nbsp;Rate는&amp;nbsp;통신에서&amp;nbsp;1초에&amp;nbsp;전송하는&amp;nbsp;심볼의&amp;nbsp;수이다.&amp;nbsp; &lt;br /&gt;비동기&amp;nbsp;통신에서는&amp;nbsp;별도의&amp;nbsp;데이터의&amp;nbsp;시작과&amp;nbsp;끝을&amp;nbsp;위한&amp;nbsp;별도의&amp;nbsp;클럭을&amp;nbsp;사용하지&amp;nbsp;않고&amp;nbsp;1bit의&amp;nbsp;데이터를&amp;nbsp;확인&amp;nbsp;하기&amp;nbsp;위하여&amp;nbsp;여러&amp;nbsp;개의&amp;nbsp;샘플(16개)를&amp;nbsp;취하여&amp;nbsp;비트의&amp;nbsp;시작과&amp;nbsp;끝을&amp;nbsp;판단&amp;nbsp;한다.&amp;nbsp;2배속&amp;nbsp;모드는&amp;nbsp;비트&amp;nbsp;데이터&amp;nbsp;확인을&amp;nbsp;위해서&amp;nbsp;샘플의&amp;nbsp;수를&amp;nbsp;절반(8개)로&amp;nbsp;줄여&amp;nbsp;전송속도를&amp;nbsp;2배로&amp;nbsp;증가&amp;nbsp;시키는&amp;nbsp;방법이다.&amp;nbsp; &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송신&amp;nbsp;(TX) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;보낼&amp;nbsp;데이터(byte)를&amp;nbsp;프레임&amp;nbsp;구조로&amp;nbsp;구성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;각&amp;nbsp;비트를&amp;nbsp;일정한&amp;nbsp;속도로&amp;nbsp;순차적으로&amp;nbsp;전송 &lt;br /&gt;&lt;br /&gt;수신&amp;nbsp;(RX) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Start&amp;nbsp;Bit의&amp;nbsp;Falling&amp;nbsp;Edge를&amp;nbsp;감지&amp;nbsp;&amp;rarr;&amp;nbsp;샘플링&amp;nbsp;시작 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;정해진&amp;nbsp;시간&amp;nbsp;간격으로&amp;nbsp;Data/Parity/Stop&amp;nbsp;Bit&amp;nbsp;수신 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART의 장점 / 단점&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zhMYV/btsPht7qjyG/Nk7vck9Yxj8KQnmKtR8ca1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zhMYV/btsPht7qjyG/Nk7vck9Yxj8KQnmKtR8ca1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zhMYV/btsPht7qjyG/Nk7vck9Yxj8KQnmKtR8ca1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzhMYV%2FbtsPht7qjyG%2FNk7vck9Yxj8KQnmKtR8ca1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;443&quot; height=&quot;88&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART Transmit&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1. 비동기 통신 방식으로, 송신(TX)과 수신(RX)이 독립적으로 처리됨.&amp;nbsp; &lt;br /&gt;송신과&amp;nbsp;수신은&amp;nbsp;각각&amp;nbsp;다른&amp;nbsp;타이밍에&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;별도의&amp;nbsp;클럭&amp;nbsp;신호&amp;nbsp;없이&amp;nbsp;데이터를&amp;nbsp;송&amp;nbsp;&amp;middot;&amp;nbsp;수신함 &lt;br /&gt;&lt;br /&gt;2. 비동기이기 때문에 데이터를 받을 때, Start bit를 0으로 고정 후 데이터를 송 &amp;middot; 수신하고 마지막 끝 비트를 1로 고정시키는 인코딩 작업이 필요 &lt;br /&gt;&lt;br /&gt;3. 또한 송 &amp;middot; 수신시 Baud Rate를 고려해야 하기 때문에, 타이밍에 맞춰 인코딩 해야함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djrjTk/btsPiENrpR6/KO6ZzA9KBBXKGYwLHndbl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djrjTk/btsPiENrpR6/KO6ZzA9KBBXKGYwLHndbl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djrjTk/btsPiENrpR6/KO6ZzA9KBBXKGYwLHndbl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjrjTk%2FbtsPiENrpR6%2FKO6ZzA9KBBXKGYwLHndbl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;419&quot; height=&quot;251&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;193&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XIYZh/btsPhIJ4MSb/WbnScf8N7hkRaUqsTT29a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XIYZh/btsPhIJ4MSb/WbnScf8N7hkRaUqsTT29a0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XIYZh/btsPhIJ4MSb/WbnScf8N7hkRaUqsTT29a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXIYZh%2FbtsPhIJ4MSb%2FWbnScf8N7hkRaUqsTT29a0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;75&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;193&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KLihK/btsPjdoisPW/lIBK6fFekxsLSO9okU1Cek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KLihK/btsPjdoisPW/lIBK6fFekxsLSO9okU1Cek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KLihK/btsPjdoisPW/lIBK6fFekxsLSO9okU1Cek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKLihK%2FbtsPjdoisPW%2FlIBK6fFekxsLSO9okU1Cek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;197&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step1 : START 신호로 low signal을&amp;nbsp;&amp;nbsp;10416 ns 동안 전송(9600 BPS 기준)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step2 : 이어서 8bit의 DATA를 LSB부터 MSB까지 0 이면 low, 1이면 high 로 10416 ns 주기로 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step3 : DATA 전송을 마치고 high 로 유지&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;597&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAgxHP/btsPh6RrL3O/VI17RyvuapTIkWkLKp23lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAgxHP/btsPh6RrL3O/VI17RyvuapTIkWkLKp23lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAgxHP/btsPh6RrL3O/VI17RyvuapTIkWkLKp23lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAgxHP%2FbtsPh6RrL3O%2FVI17RyvuapTIkWkLKp23lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;141&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;597&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;System&amp;nbsp;clock&amp;nbsp;100MHz에서&amp;nbsp;9600Hz의&amp;nbsp;주파수를&amp;nbsp;만들고자&amp;nbsp;하면 &lt;br /&gt;&lt;br /&gt;1.1. 100MHz(100,000,000Hz) 의 1주기(1/100,000,000)는&amp;nbsp;0.000,000,01 sec(10ns) &lt;br /&gt;&lt;br /&gt;1.2.&amp;nbsp;System&amp;nbsp;clock&amp;nbsp;100MHz를&amp;nbsp;입력으로&amp;nbsp;해서&amp;nbsp;9600Hz의&amp;nbsp;주파수를&amp;nbsp;만들고자&amp;nbsp;하면 &lt;br /&gt;&amp;nbsp;&amp;nbsp;1)&amp;nbsp;1주기는&amp;nbsp;100MHz&amp;nbsp;/&amp;nbsp;9600Hz&amp;nbsp;&amp;nbsp;10416.666ns(104.16us)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;2)&amp;nbsp;&amp;nbsp;결국 1주기가 10416.666ns 짜리 가 9600번 반복하면 100MHz(100,000,000Hz)가 생성 된다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- system clock의 100MHz의 1주기가 10ns로써 10416.666ns를&amp;nbsp;count하기 위해서는 10416번 count 한다.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; 3) 여기서 50% Duty cycle을 유지 하고자 한다면 10416.666ns의 절반인&amp;nbsp;&amp;nbsp;5208.333 ns &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;System&amp;nbsp;clock이&amp;nbsp;100MHz에서&amp;nbsp;115200(bps)Hz의&amp;nbsp;주파수를&amp;nbsp;만들고자&amp;nbsp;하면 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;-&amp;nbsp;100,000,000Hz/115200bps&amp;nbsp;=&amp;nbsp;868&amp;nbsp;(CLOCK&amp;nbsp;PER&amp;nbsp;BIT) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;100MHz system clock의 115200bps 전송을 하기 위해서는 868clock당 1 bit를 송.수신&amp;nbsp;&amp;nbsp;하면 됨 &lt;br /&gt;&lt;br /&gt;UART top module block diagram&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2625&quot; data-origin-height=&quot;1438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nRvYm/btsPiHpUVMO/tQzbkkGn2DAwtzBKtdygEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nRvYm/btsPiHpUVMO/tQzbkkGn2DAwtzBKtdygEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nRvYm/btsPiHpUVMO/tQzbkkGn2DAwtzBKtdygEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnRvYm%2FbtsPiHpUVMO%2FtQzbkkGn2DAwtzBKtdygEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;301&quot; data-origin-width=&quot;2625&quot; data-origin-height=&quot;1438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART controller module block diagram&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2630&quot; data-origin-height=&quot;1456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCvmDG/btsPhsOcox8/Ky3Y0rhbFs99Yn5A5CWJh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCvmDG/btsPhsOcox8/Ky3Y0rhbFs99Yn5A5CWJh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCvmDG/btsPhsOcox8/Ky3Y0rhbFs99Yn5A5CWJh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCvmDG%2FbtsPhsOcox8%2FKy3Y0rhbFs99Yn5A5CWJh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;297&quot; data-origin-width=&quot;2630&quot; data-origin-height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART 송신 module uart_tx&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YF1Ok/btsPjeHvcFV/lGHk3F10GPnwZ3l8kNEEk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YF1Ok/btsPjeHvcFV/lGHk3F10GPnwZ3l8kNEEk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YF1Ok/btsPjeHvcFV/lGHk3F10GPnwZ3l8kNEEk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYF1Ok%2FbtsPjeHvcFV%2FlGHk3F10GPnwZ3l8kNEEk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1582&quot; height=&quot;661&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZhrV/btsPh8aIoVz/ALdW4xwimnhSYZ2r52gM2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZhrV/btsPh8aIoVz/ALdW4xwimnhSYZ2r52gM2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZhrV/btsPh8aIoVz/ALdW4xwimnhSYZ2r52gM2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZhrV%2FbtsPh8aIoVz%2FALdW4xwimnhSYZ2r52gM2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1890&quot; height=&quot;930&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure data-ke-type=&quot;image&quot; data-ke-style=&quot;alignCenter&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/540</guid>
      <comments>https://hotari.tistory.com/540#entry540comment</comments>
      <pubDate>Wed, 16 Jul 2025 09:08:10 +0900</pubDate>
    </item>
    <item>
      <title>11일차 mini Project3 - Microwave_System</title>
      <link>https://hotari.tistory.com/539</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.14&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#&amp;nbsp; &amp;nbsp;Verilog&amp;nbsp;Microwave&amp;nbsp;Oven&amp;nbsp;System&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Basys3&amp;nbsp;FPGA&amp;nbsp;기반의&amp;nbsp;Verilog&amp;nbsp;HDL&amp;nbsp;프로젝트로,&amp;nbsp;실생활&amp;nbsp;전자레인지의&amp;nbsp;핵심&amp;nbsp;기능을&amp;nbsp;디지털&amp;nbsp;회로로&amp;nbsp;구현하였습니다.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;프로젝트&amp;nbsp;개요&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;프로젝트는&amp;nbsp;전자레인지의&amp;nbsp;주요&amp;nbsp;기능을&amp;nbsp;FPGA&amp;nbsp;보드에서&amp;nbsp;구현한&amp;nbsp;것입니다.&amp;nbsp;&amp;nbsp;&lt;br /&gt;사용자는&amp;nbsp;버튼을&amp;nbsp;통해&amp;nbsp;시간을&amp;nbsp;설정하고,&amp;nbsp;조리&amp;nbsp;과정을&amp;nbsp;시작하며,&amp;nbsp;모터&amp;nbsp;및&amp;nbsp;서보,&amp;nbsp;부저를&amp;nbsp;통한&amp;nbsp;피드백을&amp;nbsp;제공합니다.&lt;br /&gt;&lt;br /&gt;&amp;gt;&amp;nbsp;타이머&amp;nbsp;설정&amp;nbsp;&amp;rarr;&amp;nbsp;모터&amp;nbsp;회전&amp;nbsp;및&amp;nbsp;동작&amp;nbsp;&amp;rarr;&amp;nbsp;종료&amp;nbsp;시&amp;nbsp;알림음&amp;nbsp;및&amp;nbsp;서보&amp;nbsp;제어&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; ️&amp;nbsp;주요&amp;nbsp;기능&amp;nbsp;요약&lt;br /&gt;&lt;br /&gt;|&amp;nbsp;기능&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;설명&amp;nbsp;|&lt;br /&gt;|-----------------------|------|&lt;br /&gt;|&amp;nbsp;⏱&amp;nbsp;타이머&amp;nbsp;설정&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;버튼으로&amp;nbsp;초&amp;nbsp;단위&amp;nbsp;시간&amp;nbsp;설정&amp;nbsp;(`btn_U`,&amp;nbsp;`btn_D`)&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;▶&amp;nbsp;조리&amp;nbsp;시작/취소&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;`btn_run`으로&amp;nbsp;시작,&amp;nbsp;`btn_D`로&amp;nbsp;취소&amp;nbsp;가능&amp;nbsp;|&lt;br /&gt;|&amp;nbsp; &amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;회전&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;조리&amp;nbsp;시간&amp;nbsp;동안&amp;nbsp;자동&amp;nbsp;PWM&amp;nbsp;회전&amp;nbsp;|&lt;br /&gt;|&amp;nbsp; &amp;nbsp;부저&amp;nbsp;출력&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;버튼&amp;nbsp;입력&amp;nbsp;시&amp;nbsp;BEEP,&amp;nbsp;종료&amp;nbsp;시&amp;nbsp;알림음&amp;nbsp;|&lt;br /&gt;|&amp;nbsp; &amp;nbsp;서보모터&amp;nbsp;문&amp;nbsp;제어&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;`btn_L`로&amp;nbsp;열기,&amp;nbsp;`btn_R`로&amp;nbsp;닫기&amp;nbsp;|&lt;br /&gt;|&amp;nbsp; &amp;nbsp;FND&amp;nbsp;디스플레이&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;남은&amp;nbsp;시간&amp;nbsp;출력&amp;nbsp;|&lt;br /&gt;|&amp;nbsp; &amp;nbsp;방향&amp;nbsp;제어&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;SW14,&amp;nbsp;SW15를&amp;nbsp;통해&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;방향&amp;nbsp;설정&amp;nbsp;가능&amp;nbsp;(`in1_in2`)&amp;nbsp;|&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;프로젝트&amp;nbsp;구조&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;├──&amp;nbsp;top_module.v&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;전체&amp;nbsp;시스템&amp;nbsp;통합&amp;nbsp;FSM&lt;br /&gt;├──&amp;nbsp;btn_controller.v&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;버튼&amp;nbsp;디바운싱&amp;nbsp;+&amp;nbsp;펄스&amp;nbsp;생성&lt;br /&gt;├──&amp;nbsp;fnd_controller.v&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;FND로&amp;nbsp;남은&amp;nbsp;시간&amp;nbsp;표시&amp;nbsp;및&amp;nbsp;타이머&amp;nbsp;FSM&lt;br /&gt;├──&amp;nbsp;buzzer_controller.v&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;부저&amp;nbsp;제어&lt;br /&gt;├──&amp;nbsp;dc_controller.v&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;PWM&amp;nbsp;제어&amp;nbsp;(타이머&amp;nbsp;연동)&lt;br /&gt;├──&amp;nbsp;servo_motor_controller.v&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;서보모터&amp;nbsp;PWM&amp;nbsp;제어&amp;nbsp;(수동&amp;nbsp;버튼)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;시스템&amp;nbsp;동작&amp;nbsp;흐름&lt;br /&gt;&lt;br /&gt;```mermaid&lt;br /&gt;stateDiagram-v2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[*]&amp;nbsp;--&amp;gt;&amp;nbsp;CIRCLE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CIRCLE&amp;nbsp;--&amp;gt;&amp;nbsp;IDLE:&amp;nbsp;sw0&amp;nbsp;==&amp;nbsp;1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IDLE&amp;nbsp;--&amp;gt;&amp;nbsp;SET_TIME:&amp;nbsp;btn_U&amp;nbsp;or&amp;nbsp;btn_D&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SET_TIME&amp;nbsp;--&amp;gt;&amp;nbsp;RUNNING:&amp;nbsp;btn_run&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RUNNING&amp;nbsp;--&amp;gt;&amp;nbsp;DONE:&amp;nbsp;timer&amp;nbsp;done&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RUNNING&amp;nbsp;--&amp;gt;&amp;nbsp;IDLE:&amp;nbsp;btn_D&amp;nbsp;(cancel)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DONE&amp;nbsp;--&amp;gt;&amp;nbsp;IDLE&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;입출력&amp;nbsp;핀&amp;nbsp;구성&lt;br /&gt;&lt;br /&gt;|&amp;nbsp;핀/스위치&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;설명&amp;nbsp;|&lt;br /&gt;|--------------|------|&lt;br /&gt;|&amp;nbsp;`btn_U`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;시간&amp;nbsp;증가&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`btn_D`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;시간&amp;nbsp;감소&amp;nbsp;/&amp;nbsp;취소&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`btn_L`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;서보모터&amp;nbsp;문&amp;nbsp;열기&amp;nbsp;(0도)&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`btn_R`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;서보모터&amp;nbsp;문&amp;nbsp;닫기&amp;nbsp;(180도)&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`btn_run`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;조리&amp;nbsp;시작&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`sw`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;모드&amp;nbsp;선택&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`sw14~15`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;방향&amp;nbsp;제어&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`in1_in2`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;제어&amp;nbsp;핀&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`PWM_OUT`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;PWM&amp;nbsp;출력&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`servo_out`&amp;nbsp;&amp;nbsp;|&amp;nbsp;서보모터&amp;nbsp;PWM&amp;nbsp;출력&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`buzzer`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;부저&amp;nbsp;신호&amp;nbsp;출력&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`seg_data`&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;7-segment&amp;nbsp;데이터&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;`an`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;FND&amp;nbsp;자리&amp;nbsp;선택&amp;nbsp;|&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;시연&amp;nbsp;영상&lt;br /&gt;&lt;br /&gt; &amp;nbsp;[YouTube&amp;nbsp;시연&amp;nbsp;영상&amp;nbsp;바로&amp;nbsp;보기](&lt;a href=&quot;https://youtube.com/shorts/ziCvCQJrvrs)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/ziCvCQJrvrs)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&amp;gt;&amp;nbsp;영상에서는&amp;nbsp;버튼을&amp;nbsp;이용한&amp;nbsp;시간&amp;nbsp;설정,&amp;nbsp;조리&amp;nbsp;시작,&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;회전,&amp;nbsp;FND&amp;nbsp;출력,&amp;nbsp;서보모터&amp;nbsp;문&amp;nbsp;제어,&amp;nbsp;부저&amp;nbsp;반응&amp;nbsp;등의&amp;nbsp;전체&amp;nbsp;동작&amp;nbsp;흐름을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;⚙️&amp;nbsp;구현&amp;nbsp;상세&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;**DC&amp;nbsp;모터는&amp;nbsp;타이머&amp;nbsp;동작&amp;nbsp;중&amp;nbsp;자동&amp;nbsp;회전**,&amp;nbsp;종료되면&amp;nbsp;PWM&amp;nbsp;출력이&amp;nbsp;0으로&amp;nbsp;꺼짐&lt;br /&gt;-&amp;nbsp;**서보모터는&amp;nbsp;버튼&amp;nbsp;입력(`btn_L`,&amp;nbsp;`btn_R`)으로&amp;nbsp;직접&amp;nbsp;열고&amp;nbsp;닫음**&lt;br /&gt;-&amp;nbsp;**부저는&amp;nbsp;타이머&amp;nbsp;종료&amp;nbsp;시&amp;nbsp;알림음&amp;nbsp;출력**&lt;br /&gt;-&amp;nbsp;**FND는&amp;nbsp;남은&amp;nbsp;시간&amp;nbsp;출력&amp;nbsp;또는&amp;nbsp;0점멸&amp;nbsp;애니메이션**&lt;br /&gt;-&amp;nbsp;**모터&amp;nbsp;방향은&amp;nbsp;SW14,&amp;nbsp;SW15에&amp;nbsp;따라&amp;nbsp;`in1_in2`로&amp;nbsp;전달**&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;테스트&amp;nbsp;및&amp;nbsp;시뮬레이션&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;FPGA&amp;nbsp;실제&amp;nbsp;배치&amp;nbsp;후&amp;nbsp;하드웨어&amp;nbsp;디버깅&amp;nbsp;완료&lt;br /&gt;-&amp;nbsp;PWM&amp;nbsp;파형,&amp;nbsp;FND&amp;nbsp;타이밍,&amp;nbsp;서보&amp;nbsp;제어&amp;nbsp;파형&amp;nbsp;모두&amp;nbsp;확인&lt;br /&gt;-&amp;nbsp;Simulation&amp;nbsp;없이&amp;nbsp;실제&amp;nbsp;동작&amp;nbsp;중심으로&amp;nbsp;검증&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;Vivado&amp;nbsp;프로젝트&amp;nbsp;설정&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;**Board**:&amp;nbsp;Digilent&amp;nbsp;Basys3&amp;nbsp;(Artix-7&amp;nbsp;xc7a35tcpg236-1)&lt;br /&gt;-&amp;nbsp;**Clock**:&amp;nbsp;100&amp;nbsp;MHz&lt;br /&gt;-&amp;nbsp;**Constraints**:&amp;nbsp;Basys3-Master.xdc&amp;nbsp;사용&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp; &amp;nbsp;참고&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;서보모터&amp;nbsp;PWM:&amp;nbsp;50Hz&amp;nbsp;기준&amp;nbsp;(1ms~2ms&amp;nbsp;=&amp;nbsp;0도~180도)&lt;br /&gt;-&amp;nbsp;DC&amp;nbsp;모터&amp;nbsp;PWM:&amp;nbsp;10단계&amp;nbsp;듀티&amp;nbsp;설정&amp;nbsp;가능&amp;nbsp;(0~9)&lt;br /&gt;-&amp;nbsp;FND:&amp;nbsp;4-digit&amp;nbsp;multiplexing&amp;nbsp;방식,&amp;nbsp;timer&amp;nbsp;카운트와&amp;nbsp;blink&amp;nbsp;상태&amp;nbsp;병행&amp;nbsp;출력&lt;br /&gt;&lt;br /&gt;---&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/microwave&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/microwave&lt;/a&gt;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/539</guid>
      <comments>https://hotari.tistory.com/539#entry539comment</comments>
      <pubDate>Mon, 14 Jul 2025 12:42:22 +0900</pubDate>
    </item>
    <item>
      <title>10일차</title>
      <link>https://hotari.tistory.com/538</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.11&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;휴가&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/538</guid>
      <comments>https://hotari.tistory.com/538#entry538comment</comments>
      <pubDate>Mon, 14 Jul 2025 12:41:02 +0900</pubDate>
    </item>
    <item>
      <title>9일차</title>
      <link>https://hotari.tistory.com/537</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.10&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;buzzer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;buzzer_top.v&lt;/p&gt;
&lt;pre id=&quot;code_1752133998811&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module top(
    input clk,
    input reset,
    input btnL,
    input btnR,
    output buzzer
);

    wire clean_btnL, clean_btnR;
    wire buzzer_L, buzzer_R;

    // 버튼 디바운스
    button_debounce dbL (
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(btnL),
        .o_btn_clean(clean_btnL)
    );

    button_debounce dbR (
        .i_clk(clk),
        .i_reset(reset),
        .i_btn(btnR),
        .o_btn_clean(clean_btnR)
    );

    // 파워 온 시퀀스 (btnL)
    power_on_buzzer u_power (
        .clk(clk),
        .reset(reset),
        .btnL(clean_btnL),
        .buzzer_L(buzzer_L)
    );

    // 오픈 시퀀스 (btnR)
    open_buzzer u_open (
        .clk(clk),
        .reset(reset),
        .btnR(clean_btnR),
        .buzzer_R(buzzer_R)
    );

    assign buzzer = buzzer_L | buzzer_R;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;power_on_buzzer.v&lt;/p&gt;
&lt;pre id=&quot;code_1752134007878&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module power_on_buzzer(
    input clk,
    input reset,
    input btnL,
    output reg buzzer_L
);

    parameter CNT_70MS = 23'd7000000;
    parameter CNT_3S   = 29'd300000000;

    parameter HALF_1K = 17'd50000;
    parameter HALF_2K = 17'd25000;
    parameter HALF_3K = 17'd16667;
    parameter HALF_4K = 17'd12500;

    reg btnL_d1, btnL_d2;
    wire btnL_edge = btnL_d1 &amp;amp; ~btnL_d2;

    always @(posedge clk) begin
        btnL_d1 &amp;lt;= btnL;
        btnL_d2 &amp;lt;= btnL_d1;
    end

    reg run = 0;
    reg [2:0] step = 0;
    reg [28:0] dur_cnt = 0;
    reg [17:0] wave_cnt = 0;
    reg [17:0] half_cycle = 0;

    always @(*) begin
        case (step)
            0: half_cycle = HALF_1K;
            1: half_cycle = HALF_2K;
            2: half_cycle = HALF_3K;
            3: half_cycle = HALF_4K;
            default: half_cycle = 0;
        endcase
    end

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            run &amp;lt;= 0; step &amp;lt;= 0; dur_cnt &amp;lt;= 0; wave_cnt &amp;lt;= 0; buzzer_L &amp;lt;= 0;
        end else begin
            if (btnL_edge) run &amp;lt;= ~run;
            if (!run) begin
                step &amp;lt;= 0; dur_cnt &amp;lt;= 0; wave_cnt &amp;lt;= 0; buzzer_L &amp;lt;= 0;
            end else begin
                if ((step &amp;lt; 4 &amp;amp;&amp;amp; dur_cnt &amp;gt;= CNT_70MS) || (step == 4 &amp;amp;&amp;amp; dur_cnt &amp;gt;= CNT_3S)) begin
                    dur_cnt &amp;lt;= 0;
                    step &amp;lt;= (step == 4) ? 0 : step + 1;
                end else begin
                    dur_cnt &amp;lt;= dur_cnt + 1;
                end

                if (half_cycle != 0) begin
                    if (wave_cnt &amp;gt;= half_cycle) begin
                        wave_cnt &amp;lt;= 0;
                        buzzer_L &amp;lt;= ~buzzer_L;
                    end else wave_cnt &amp;lt;= wave_cnt + 1;
                end else begin
                    buzzer_L &amp;lt;= 0;
                    wave_cnt &amp;lt;= 0;
                end
            end
        end
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;open_buzzer.v&lt;/p&gt;
&lt;pre id=&quot;code_1752134015861&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module open_buzzer(
    input clk,
    input reset,
    input btnR,
    output reg buzzer_R
);

    parameter CNT_70MS = 23'd7000000;
    parameter CNT_3S   = 29'd300000000;

    parameter HALF_261 = 18'd192000;
    parameter HALF_329 = 18'd152000;
    parameter HALF_392 = 18'd128000;
    parameter HALF_554 = 18'd90000;

    reg btnR_d1, btnR_d2;
    wire btnR_edge = btnR_d1 &amp;amp; ~btnR_d2;

    always @(posedge clk) begin
        btnR_d1 &amp;lt;= btnR;
        btnR_d2 &amp;lt;= btnR_d1;
    end

    reg run = 0;
    reg [2:0] step = 0;
    reg [28:0] dur_cnt = 0;
    reg [17:0] wave_cnt = 0;
    reg [17:0] half_cycle = 0;

    always @(*) begin
        case (step)
            0: half_cycle = HALF_261;
            1: half_cycle = HALF_329;
            2: half_cycle = HALF_392;
            3: half_cycle = HALF_554;
            default: half_cycle = 0;
        endcase
    end

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            run &amp;lt;= 0; step &amp;lt;= 0; dur_cnt &amp;lt;= 0; wave_cnt &amp;lt;= 0; buzzer_R &amp;lt;= 0;
        end else begin
            if (btnR_edge) run &amp;lt;= ~run;
            if (!run) begin
                step &amp;lt;= 0; dur_cnt &amp;lt;= 0; wave_cnt &amp;lt;= 0; buzzer_R &amp;lt;= 0;
            end else begin
                if ((step &amp;lt; 4 &amp;amp;&amp;amp; dur_cnt &amp;gt;= CNT_70MS) || (step == 4 &amp;amp;&amp;amp; dur_cnt &amp;gt;= CNT_3S)) begin
                    dur_cnt &amp;lt;= 0;
                    step &amp;lt;= (step == 4) ? 0 : step + 1;
                end else begin
                    dur_cnt &amp;lt;= dur_cnt + 1;
                end

                if (half_cycle != 0) begin
                    if (wave_cnt &amp;gt;= half_cycle) begin
                        wave_cnt &amp;lt;= 0;
                        buzzer_R &amp;lt;= ~buzzer_R;
                    end else wave_cnt &amp;lt;= wave_cnt + 1;
                end else begin
                    buzzer_R &amp;lt;= 0;
                    wave_cnt &amp;lt;= 0;
                end
            end
        end
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;button_debounce.v&lt;/p&gt;
&lt;pre id=&quot;code_1752134024919&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module button_debounce #(parameter DEBOUNCE_LIMIT = 20'd999_999) (
    input      i_clk,
    input      i_reset,
    input      i_btn,
    output    reg  o_btn_clean  
);
    reg [19:0] count;
    reg btn_state;
    reg btn_clean;

    always @(posedge i_clk, posedge i_reset) begin
        if (i_reset) begin
            count &amp;lt;= 0;
            btn_state &amp;lt;= 0;
            o_btn_clean &amp;lt;= 0;
        end else if (i_btn == btn_state) begin
            count &amp;lt;= 0;
        end else begin
            if (count &amp;lt; DEBOUNCE_LIMIT)
                count &amp;lt;= count + 1;
            else begin
                btn_state &amp;lt;= i_btn;
                o_btn_clean &amp;lt;= i_btn;
                count &amp;lt;= 0;  // 리셋하면 다음 변경을 다시 감지할 수 있음
            end
        end
    end
    
endmodule&lt;/code&gt;&lt;/pre&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/537</guid>
      <comments>https://hotari.tistory.com/537#entry537comment</comments>
      <pubDate>Thu, 10 Jul 2025 16:53:53 +0900</pubDate>
    </item>
    <item>
      <title>8일차</title>
      <link>https://hotari.tistory.com/535</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.09&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shift_register &amp;amp; FSM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;btnU 를 누르면 1이 btnD를 누르면 0이 입력 되도록 구현&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;입력 되는 상황은 led6~led0로 left shift표시 되도록 하고 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;동일한 입력 2개(00 또는 11) 발견 시&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;00이면 led15 on 11이면 led14를 on&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;그렇지 않은 경우는 led15 led14를 off로 처리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;777&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kDd4o/btsPaYkxGqT/JQUX2MdKXw9gFgDFaktr60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kDd4o/btsPaYkxGqT/JQUX2MdKXw9gFgDFaktr60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kDd4o/btsPaYkxGqT/JQUX2MdKXw9gFgDFaktr60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkDd4o%2FbtsPaYkxGqT%2FJQUX2MdKXw9gFgDFaktr60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;215&quot; height=&quot;303&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;777&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1794&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkie5x/btsPaH4qonB/YwFakw6Vr0Z0m2vafeF6F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkie5x/btsPaH4qonB/YwFakw6Vr0Z0m2vafeF6F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkie5x/btsPaH4qonB/YwFakw6Vr0Z0m2vafeF6F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkie5x%2FbtsPaH4qonB%2FYwFakw6Vr0Z0m2vafeF6F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1794&quot; height=&quot;565&quot; data-origin-width=&quot;1794&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3c4043; text-align: start;&quot;&gt;top.v&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752029286014&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module pattern_detector_top (
    input  wire clk,
    input  wire rst,      // 동기 리셋
    input  wire btnU,     // 1 입력 버튼
    input  wire btnD,     // 0 입력 버튼
    output wire [15:0] led // led[6:0] = 입력 표시, led[7] = 패턴 감지
);

    wire clean_btnU, clean_btnD;
    wire pulse_btnU, pulse_btnD;

    // 디바운싱
    button_debouncer db_u (
        .clk(clk),
        .btn(btnU),
        .debounced(clean_btnU)
    );

    button_debouncer db_d (
        .clk(clk),
        .btn(btnD),
        .debounced(clean_btnD)
    );

    // 원샷
    one_pulse op_u (
        .clk(clk),
        .btn_in(clean_btnU),
        .pulse_out(pulse_btnU)
    );

    one_pulse op_d (
        .clk(clk),
        .btn_in(clean_btnD),
        .pulse_out(pulse_btnD)
    );

    // FSM 동작
    pattern_detector_fsm fsm (
        .clk(clk),
        .rst(rst),
        .in1(pulse_btnU),
        .in0(pulse_btnD),
        .led(led)
    );

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pattern_detector_fsm.v&lt;/p&gt;
&lt;pre id=&quot;code_1752029301369&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps


module pattern_detector_fsm (
    input wire clk,
    input wire rst,
    input wire in1,             // btnU &amp;rarr; 1
    input wire in0,             // btnD &amp;rarr; 0
    output reg [15:0] led       // led[6:0]: 입력 표시, led[14]: 11 감지, led[15]: 00 감지
);

    // 상태 정의
    parameter S_IDLE = 2'b00;
    parameter S_1ST  = 2'b01;

    reg [1:0] current_state, next_state;

    reg prev_bit;
    reg din_bit;
    reg input_valid;

    // 입력 디코딩
    always @(*) begin
        if (in1) begin
            din_bit = 1'b1;
            input_valid = 1'b1;
        end else if (in0) begin
            din_bit = 1'b0;
            input_valid = 1'b1;
        end else begin
            input_valid = 1'b0;
        end
    end

    // 입력 시프트 저장 레지스터 (입력값 자체 shift)
    reg [6:0] input_shift;

    // 상태 전이 및 출력 동작
    always @(posedge clk or posedge rst) begin
        if (rst) begin
            current_state &amp;lt;= S_IDLE;
            prev_bit &amp;lt;= 1'b0;
            input_shift &amp;lt;= 7'b0000000;
            led[15:14] &amp;lt;= 2'b00;
        end else begin
            current_state &amp;lt;= next_state;

            if (input_valid) begin
                // ⬅ 왼쪽으로 입력값 shift (0 또는 1 입력 반영)
                input_shift &amp;lt;= {input_shift[5:0], din_bit};

                // 이전 입력과 비교하여 패턴 감지
                if (din_bit == 1'b0 &amp;amp;&amp;amp; prev_bit == 1'b0) begin
                    led[15] &amp;lt;= 1'b1;  // 00
                    led[14] &amp;lt;= 1'b0;
                end else if (din_bit == 1'b1 &amp;amp;&amp;amp; prev_bit == 1'b1) begin
                    led[15] &amp;lt;= 1'b0;
                    led[14] &amp;lt;= 1'b1;  // 11
                end else begin
                    led[15] &amp;lt;= 1'b0;
                    led[14] &amp;lt;= 1'b0;  // 01 or 10
                end

                prev_bit &amp;lt;= din_bit;
            end
        end
    end

    // 상태 천이 및 출력 결합
    always @(*) begin
        next_state = current_state;

        case (current_state)
            S_IDLE: begin
                if (input_valid)
                    next_state = S_1ST;
            end

            S_1ST: begin
                next_state = S_1ST;
            end
        endcase

        // 입력 시프트값 출력 연결
        led[6:0] = input_shift;
        // 나머지 led[13:7]는 0으로 유지
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;one_pulse.v&lt;/p&gt;
&lt;pre id=&quot;code_1752029313980&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module one_pulse (
    input  wire clk,
    input  wire btn_in,
    output reg  pulse_out
);

    reg btn_delay;

    always @(posedge clk) begin
        btn_delay &amp;lt;= btn_in;
        pulse_out &amp;lt;= btn_in &amp;amp; ~btn_delay;
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;button_debouncer.v&lt;/p&gt;
&lt;pre id=&quot;code_1752029326704&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module button_debouncer (
    input  wire clk,
    input  wire btn,
    output reg  debounced
);

    reg [15:0] cnt;
    reg btn_sync, btn_prev;

    always @(posedge clk) begin
        btn_sync &amp;lt;= btn;
        if (btn_sync == btn_prev)
            cnt &amp;lt;= cnt + 1;
        else
            cnt &amp;lt;= 0;

        if (cnt == 16'hFFFF)
            debounced &amp;lt;= btn_sync;

        btn_prev &amp;lt;= btn_sync;
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 영상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/zFXQ9qYePkk&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/zFXQ9qYePkk&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/535</guid>
      <comments>https://hotari.tistory.com/535#entry535comment</comments>
      <pubDate>Wed, 9 Jul 2025 16:50:12 +0900</pubDate>
    </item>
    <item>
      <title>7일차 mini Project2 - Vending_Machine</title>
      <link>https://hotari.tistory.com/534</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.08&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shift register&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shift_top.v&lt;/p&gt;
&lt;pre id=&quot;code_1751946437768&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module shift_top (
    input  wire       clk,      // 100 MHz 클럭
    input  wire       reset,    // Active-High 리셋
    input  wire       btnU,     // &amp;lsquo;1&amp;rsquo; 입력 버튼 (Active-High)
    input  wire       btnD,     // &amp;lsquo;0&amp;rsquo; 입력 버튼 (Active-High)
    output reg  [7:0] led       // [7]=패턴 플래그, [6:0]=시프트 레지스터
);

    //--------------------------------------------------------------------------
    // 1) 버튼 동기화 &amp;amp; 원샷 펄스 생성
    //--------------------------------------------------------------------------
    reg btnU_d, btnD_d;
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            btnU_d &amp;lt;= 1'b0;
            btnD_d &amp;lt;= 1'b0;
        end else begin
            btnU_d &amp;lt;= btnU;
            btnD_d &amp;lt;= btnD;
        end
    end

    // 눌림 에지(0&amp;rarr;1)에서 한 사이클만 1이 되는 펄스
    wire pulse1 = btnU &amp;amp; ~btnU_d;
    wire pulse0 = btnD &amp;amp; ~btnD_d;

    //--------------------------------------------------------------------------
    // 2) din 생성: pulse1&amp;rarr;&amp;lsquo;1&amp;rsquo;, pulse0&amp;rarr;&amp;lsquo;0&amp;rsquo;
    //--------------------------------------------------------------------------
    reg din;
    always @(posedge clk or posedge reset) begin
        if (reset)
            din &amp;lt;= 1'b0;
        else if (pulse1)
            din &amp;lt;= 1'b1;
        else if (pulse0)
            din &amp;lt;= 1'b0;
        // else din 유지
    end

    //--------------------------------------------------------------------------
    // 3) 7비트 Shift Register: pulse1 또는 pulse0일 때만 시프트
    //--------------------------------------------------------------------------
    reg [6:0] shift_reg;
    always @(posedge clk or posedge reset) begin
        if (reset)
            shift_reg &amp;lt;= 7'b0;
        else if (pulse1)
            shift_reg &amp;lt;= { shift_reg[5:0], 1'b1 };
        else if (pulse0)
            shift_reg &amp;lt;= { shift_reg[5:0], 1'b0 };
        // else shift_reg 유지
    end

    //--------------------------------------------------------------------------
    // 4) 패턴 검출: shift_reg == 7'b1010111
    //--------------------------------------------------------------------------
    wire pattern_hit = (shift_reg == 7'b1010111) ? 1'b1 : 1'b0;

    //--------------------------------------------------------------------------
    // 5) LED 갱신
    //--------------------------------------------------------------------------
    always @(posedge clk or posedge reset) begin
        if (reset)
            led &amp;lt;= 8'b0;
        else
            led &amp;lt;= { pattern_hit, shift_reg };
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/jmxTMGEkNf0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/jmxTMGEkNf0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vending_Machine Project&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/vending_machine&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/vending_machine&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/534</guid>
      <comments>https://hotari.tistory.com/534#entry534comment</comments>
      <pubDate>Wed, 9 Jul 2025 09:48:24 +0900</pubDate>
    </item>
    <item>
      <title>6일차</title>
      <link>https://hotari.tistory.com/533</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.07&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순차회로와 FSM&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조합회로&amp;nbsp;(Combinational&amp;nbsp;Logic) &lt;br /&gt;- 값을 저장하지 못함 &lt;br /&gt;- 클럭을 사용하지 않음 &lt;br /&gt;- 입력의 변화가 출력에 바로 반영됨 &lt;br /&gt;- 예 : adders, multiplexers, decoders, encoders, gates &lt;br /&gt;&lt;br /&gt;순차회로&amp;nbsp;(Sequential&amp;nbsp;Logic) &lt;br /&gt;- 값을 저장하는 래치, 플립플롭, 레지스터, 메모리 등의 소자가 있어 상태를 저장 &lt;br /&gt;- 클럭을 사용하여 값을 저장 &lt;br /&gt;- 입력이 변화해도 주로 클럭의 에지에서 값이 반영됨 &lt;br /&gt;- 예 : counter, register, clock divider, FSM (Finite State Machine)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WWHdi/btsO6J2Ce3z/sxZvX7lDpSBICbLhkuIK9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WWHdi/btsO6J2Ce3z/sxZvX7lDpSBICbLhkuIK9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WWHdi/btsO6J2Ce3z/sxZvX7lDpSBICbLhkuIK9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWWHdi%2FbtsO6J2Ce3z%2FsxZvX7lDpSBICbLhkuIK9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;104&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순차&amp;nbsp;회로의&amp;nbsp;종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;FSM (한정된 상태를 갖는 머신) &lt;br /&gt;- Counter (계수기) &lt;br /&gt;- Clock divider (클럭 분주기) &lt;br /&gt;- FSM &lt;br /&gt;&lt;br /&gt;Register&amp;nbsp;(레지스터) &lt;br /&gt;- Shift register &lt;br /&gt;- Parallel register&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조합회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P5jTP/btsO6cxLMxr/EumlPxalDWBz0E64vDT4ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P5jTP/btsO6cxLMxr/EumlPxalDWBz0E64vDT4ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P5jTP/btsO6cxLMxr/EumlPxalDWBz0E64vDT4ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP5jTP%2FbtsO6cxLMxr%2FEumlPxalDWBz0E64vDT4ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;135&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FSM 타입의 회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tWbA5/btsO7OPGMZF/Bg0zF2JJegIVKoAeWVB8x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tWbA5/btsO7OPGMZF/Bg0zF2JJegIVKoAeWVB8x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tWbA5/btsO7OPGMZF/Bg0zF2JJegIVKoAeWVB8x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtWbA5%2FbtsO7OPGMZF%2FBg0zF2JJegIVKoAeWVB8x0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;213&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TV&amp;nbsp;channel&amp;nbsp;버튼 &lt;br /&gt;- 0, 1, 2, &amp;hellip;, 9 채널이 있는 TV가 있다고 가정하고 채널 UP과 DN 버튼으로 채널을 선택한다면 &lt;br /&gt;- 채널 UP 버튼을 눌렀을 때 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;현재 상태가 3이면 다음 상태는 4 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;현재 상태가 9라면 다음 상태는 10 &lt;br /&gt;- 채널 DN 버튼을 눌렀을 때 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;현재 상태가 3이면 다음 상태는 2 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;현재 상태가 9라면 다음 상태는 8 &lt;br /&gt;- 다음 상태는 입력과 현재상태에 의해 결정 &lt;br /&gt;- 출력은 현재상태를 바로 출력으로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;현재상태를&amp;nbsp;저장하는&amp;nbsp;순차회로로만&amp;nbsp;가능하며&amp;nbsp;조합회로로는&amp;nbsp;불가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FSM의 세부 블록 구분&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckw5KP/btsO7ysNDd7/r6N8MROGbj9aISRo5GUMn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckw5KP/btsO7ysNDd7/r6N8MROGbj9aISRo5GUMn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckw5KP/btsO7ysNDd7/r6N8MROGbj9aISRo5GUMn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckw5KP%2FbtsO7ysNDd7%2Fr6N8MROGbj9aISRo5GUMn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;358&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E7h1G/btsO6r2uRYU/kBpBKFiwXuyaVN72KSdTt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E7h1G/btsO6r2uRYU/kBpBKFiwXuyaVN72KSdTt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E7h1G/btsO6r2uRYU/kBpBKFiwXuyaVN72KSdTt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE7h1G%2FbtsO6r2uRYU%2FkBpBKFiwXuyaVN72KSdTt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;587&quot; height=&quot;288&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FSM&amp;nbsp;(Finite&amp;nbsp;State&amp;nbsp;Machine),&amp;nbsp;유한&amp;nbsp;상태&amp;nbsp;머신의&amp;nbsp;개념 &lt;br /&gt;- 유한한 개수의 상태를 가지고 있으며 &lt;br /&gt;- 입력과 현재상태에 따라 다음상태가 결정되고 &lt;br /&gt;- (입력과) 현재상태에 따라 출력이 결정되는 머신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FSM&amp;nbsp;세부&amp;nbsp;블록 &lt;br /&gt;- Next state logic (조합회로) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;입력(input) + 현재상태(present state) &amp;rarr; 조합회로 &amp;rarr; 다음상태(next state) &lt;br /&gt;&lt;br /&gt;- State register (순차회로, F/F) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;다음상태(next state) &amp;rarr; clock edge에서 저장 &amp;rarr; 현재상태(present state) &lt;br /&gt;&lt;br /&gt;- Output logic (조합회로) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Moore machine의 경우 : 현재상태(present state) &amp;rarr; 조합회로 &amp;rarr; 다음상태(next state) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Mealy machine의 경우 : 입력(input) + 현재상태(present state) &amp;rarr; 조합회로 &amp;rarr; 다음상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 상태 다이어그램의 일반적인 표기법 &lt;br /&gt;- 현재상태가 st0일 경우 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;출력 done = 1 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;만약 in=1 이면 출력은 out = 0, 다음 상태는 st1&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/otMzN/btsO7yzxIxr/UJMxk4bBuejr68ga5xd6tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/otMzN/btsO7yzxIxr/UJMxk4bBuejr68ga5xd6tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/otMzN/btsO7yzxIxr/UJMxk4bBuejr68ga5xd6tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FotMzN%2FbtsO7yzxIxr%2FUJMxk4bBuejr68ga5xd6tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;265&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태표 (State Table)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mVGip/btsO6n6Uh5L/oEISiY83i9vpysKsPQycRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mVGip/btsO6n6Uh5L/oEISiY83i9vpysKsPQycRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mVGip/btsO6n6Uh5L/oEISiY83i9vpysKsPQycRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmVGip%2FbtsO6n6Uh5L%2FoEISiY83i9vpysKsPQycRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;221&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TV Channel 버튼 Verilog code&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YwWVx/btsO6iqXcnT/r5qzR1wiQgOEmuBx8QpJf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YwWVx/btsO6iqXcnT/r5qzR1wiQgOEmuBx8QpJf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YwWVx/btsO6iqXcnT/r5qzR1wiQgOEmuBx8QpJf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYwWVx%2FbtsO6iqXcnT%2Fr5qzR1wiQgOEmuBx8QpJf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;360&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tv_channel.v&lt;/p&gt;
&lt;pre id=&quot;code_1751857060538&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module tv_channel(
    input wire clk,
    input wire rstn,
    input wire up,
    input wire dn,
    output [3:0] ch
    );

    reg [3:0] state, next_state;

    always @(up or dn or state) begin
        if (up &amp;amp; ~dn) begin
            if (state == 9) 
                next_state = 0;
            else 
                next_state = state + 1;
        end
        else if (~up &amp;amp; dn) begin
            if (state == 0) 
                next_state = 9;
            else 
                next_state = state - 1;
        end else begin
            next_state = state;
        end
    end

    always @(posedge clk or negedge rstn) begin
        if (!rstn) 
            state &amp;lt;= 4'h0;
        else 
            state &amp;lt;= next_state;
    end

    assign ch = state;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tb_tv_channel.v&lt;/p&gt;
&lt;pre id=&quot;code_1751857100659&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module tb_ch();


    reg clk, rstn;
    reg up, dn;
    wire [3:0] ch;


    tv_channel dut_tv(
    .clk(clk),
    .rstn(rstn),
    .up(up), .dn(dn),
    .ch(ch)
    );


    initial clk = 0;
    always #5 clk = ~ clk;

    initial begin
        #0 rstn = 1; up = 1'b1; dn = 1'b0;
        #90 up = 1'b0; dn = 1'b1;
        #50 up = 1'b1;
        #20 up = 1'b0; dn = 1'b0;
        #30 up = 1'b0; dn = 1'b0;
        #120 $finish;
    end
endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TV Channel 버튼 Simulation 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgJH9T/btsO7Pnykkv/Ke7kI8jt3cDjC56WRIMjK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgJH9T/btsO7Pnykkv/Ke7kI8jt3cDjC56WRIMjK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgJH9T/btsO7Pnykkv/Ke7kI8jt3cDjC56WRIMjK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgJH9T%2FbtsO7Pnykkv%2FKe7kI8jt3cDjC56WRIMjK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1053&quot; height=&quot;273&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn5Loo/btsO6ePRa12/379P0EeQhue5zjjihdyLdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn5Loo/btsO6ePRa12/379P0EeQhue5zjjihdyLdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn5Loo/btsO6ePRa12/379P0EeQhue5zjjihdyLdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn5Loo%2FbtsO6ePRa12%2F379P0EeQhue5zjjihdyLdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1609&quot; height=&quot;245&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터 회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQi96R/btsO682a0YT/FTG5d9Tn6ElI8S7ohFTGJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQi96R/btsO682a0YT/FTG5d9Tn6ElI8S7ohFTGJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQi96R/btsO682a0YT/FTG5d9Tn6ElI8S7ohFTGJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQi96R%2FbtsO682a0YT%2FFTG5d9Tn6ElI8S7ohFTGJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;324&quot; height=&quot;112&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이프라인(Pipeline) 형태의 회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kSDiZ/btsO745P9jR/zAeBmjxBGLpnfstysgJLT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kSDiZ/btsO745P9jR/zAeBmjxBGLpnfstysgJLT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kSDiZ/btsO745P9jR/zAeBmjxBGLpnfstysgJLT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkSDiZ%2FbtsO745P9jR%2FzAeBmjxBGLpnfstysgJLT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;348&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Blocking과 Nonblocking 할당문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩&amp;nbsp;가이드라인 &lt;br /&gt;- 가이드라인-1：순차회로 또는 래치를 모델링하는 always 블록에서는 nonblocking 할당문을 사용한다. &lt;br /&gt;- 가이드라인-2：조합논리회로를 모델링하는 always 블록에서는 blocking 할당문을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ILlSY/btsO5NE4XzX/JKQp8g27RYKsySwkIg5as0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ILlSY/btsO5NE4XzX/JKQp8g27RYKsySwkIg5as0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ILlSY/btsO5NE4XzX/JKQp8g27RYKsySwkIg5as0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FILlSY%2FbtsO5NE4XzX%2FJKQp8g27RYKsySwkIg5as0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;234&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가이드라인-3：동일한 always 블록에서 순차회로와 조합논리회로를 함께 표현하는 경우에는 nonblocking 할당문을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GOJzm/btsO6xg8K8F/cgWOkcDiBitnqkTGbkkGz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GOJzm/btsO6xg8K8F/cgWOkcDiBitnqkTGbkkGz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GOJzm/btsO6xg8K8F/cgWOkcDiBitnqkTGbkkGz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGOJzm%2FbtsO6xg8K8F%2FcgWOkcDiBitnqkTGbkkGz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;199&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가이드라인-4：동일한 always 블록 내에서 blocking 할당문과 nonblocking&amp;nbsp;할당문을&amp;nbsp;혼합해서&amp;nbsp;사용하지&amp;nbsp;않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duUUHX/btsO77axVcY/jRiMkV2yZ5wpX3LkhIXggk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duUUHX/btsO77axVcY/jRiMkV2yZ5wpX3LkhIXggk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duUUHX/btsO77axVcY/jRiMkV2yZ5wpX3LkhIXggk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduUUHX%2FbtsO77axVcY%2FjRiMkV2yZ5wpX3LkhIXggk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;382&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zz3hv/btsO6e3two9/6qAKRqhikJ2lDaC1CU55tK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zz3hv/btsO6e3two9/6qAKRqhikJ2lDaC1CU55tK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zz3hv/btsO6e3two9/6qAKRqhikJ2lDaC1CU55tK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzz3hv%2FbtsO6e3two9%2F6qAKRqhikJ2lDaC1CU55tK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;421&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가이드라인-5：다수의 always 블록에서 동일한 reg 변수에 값을 할당하지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4gWiv/btsO6DaEKsn/7aGE0tNR2K1qW2AMP7VF40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4gWiv/btsO6DaEKsn/7aGE0tNR2K1qW2AMP7VF40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4gWiv/btsO6DaEKsn/7aGE0tNR2K1qW2AMP7VF40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4gWiv%2FbtsO6DaEKsn%2F7aGE0tNR2K1qW2AMP7VF40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;303&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하지&amp;nbsp;않는&amp;nbsp;래치의&amp;nbsp;합성 &lt;br /&gt;일반적으로,&amp;nbsp;case&amp;nbsp;문에&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;case&amp;nbsp;항목들이&amp;nbsp;포함되지&amp;nbsp;않거나&amp;nbsp;if&amp;nbsp;조건문에서 &lt;br /&gt;else&amp;nbsp;블록이&amp;nbsp;생략되는&amp;nbsp;경우가&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;case&amp;nbsp;문과&amp;nbsp;if&amp;nbsp;조건문에&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;조건들이&amp;nbsp;포함되지&amp;nbsp;않은&amp;nbsp;경우를&amp;nbsp;&amp;lsquo;불완전한&amp;nbsp;조건&amp;nbsp;지정&amp;rsquo;이라고&amp;nbsp;한다. &lt;br /&gt;조합논리회로의&amp;nbsp;HDL&amp;nbsp;모델링에서는&amp;nbsp;입력의&amp;nbsp;모든&amp;nbsp;경우에&amp;nbsp;대해&amp;nbsp;출력값이&amp;nbsp;지정되어야&amp;nbsp;한다.&amp;nbsp;case&amp;nbsp;문에서&amp;nbsp;입력의&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;경우에&amp;nbsp;대하여&amp;nbsp;명시적으로&amp;nbsp;출력값이&amp;nbsp;지정되지&amp;nbsp;않으면, &lt;br /&gt;출력값이&amp;nbsp;지정되지&amp;nbsp;않은&amp;nbsp;입력&amp;nbsp;조건에&amp;nbsp;대해서는&amp;nbsp;이전에&amp;nbsp;지정된&amp;nbsp;출력값을&amp;nbsp;계속&amp;nbsp;유지하는&amp;nbsp;것으로&amp;nbsp;해석될&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;논리&amp;nbsp;합성&amp;nbsp;툴은&amp;nbsp;암시적으로&amp;nbsp;래치를&amp;nbsp;생성하게&amp;nbsp;된다.&amp;nbsp;래치가&amp;nbsp;포함된&amp;nbsp;회로는 &lt;br /&gt;순차논리회로가&amp;nbsp;되므로&amp;nbsp;합성된&amp;nbsp;회로는&amp;nbsp;원래&amp;nbsp;의도했던&amp;nbsp;조합논리회로로&amp;nbsp;동작하지&amp;nbsp;않게&amp;nbsp;된다. &lt;br /&gt;따라서&amp;nbsp;case&amp;nbsp;문&amp;nbsp;또는&amp;nbsp;if&amp;nbsp;조건문으로&amp;nbsp;조합논리회로를&amp;nbsp;모델링하는&amp;nbsp;경우에는&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;입력&amp;nbsp;조건들에&amp;nbsp;대해&amp;nbsp;출력값을&amp;nbsp;명시적으로&amp;nbsp;지정하거나,&amp;nbsp;또는&amp;nbsp;default&amp;nbsp;값을&amp;nbsp;지정해야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;원하지&amp;nbsp;않는&amp;nbsp;래치의&amp;nbsp;합성 &lt;br /&gt;&lt;br /&gt;case&amp;nbsp;문에&amp;nbsp;모든&amp;nbsp;가능한&amp;nbsp;case&amp;nbsp;항목들이&amp;nbsp;포함되지&amp;nbsp;않는&amp;nbsp;경우 &lt;br /&gt;if&amp;nbsp;조건문에서&amp;nbsp;else&amp;nbsp;블록이&amp;nbsp;생략되는&amp;nbsp;경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;nbsp;순수한&amp;nbsp;조합논리회로의&amp;nbsp;합성 &lt;br /&gt;&lt;br /&gt;모든&amp;nbsp;가능한&amp;nbsp;입력&amp;nbsp;조건들에&amp;nbsp;대해&amp;nbsp;출력값을&amp;nbsp;명시적으로&amp;nbsp;지정 &lt;br /&gt;default&amp;nbsp;값을&amp;nbsp;지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순차회로 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;현재의 입력과 현재 상태에 의해 다음 상태와 출력이 결정되는 회로 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;기억소자(래치, 플립플롭, SRAM)와 조합논리회로로 구성 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;레지스터, 주파수 분주기, 계수기(counter), 유한상태머신(Finite State Machine; FSM)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;래치와&amp;nbsp;플립플롭 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;래치(latch) : 클록의 레벨(즉, 0 또는 1)에 따라 동작하는 저장소자 =&amp;gt; 사용안함 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;플립플롭(Flip/flop) : 클록의 상승 또는 하강에지에 동기되어 동작하는 저장소자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;순차회로의 모델링 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;always 구문만을 사용 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;이벤트 리스트에는 edge-sensitive이므로 posedge 또는 negedge가 있는 clock이나 reset, preset만을 사용 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;변수는 reg로 선언 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;할당문은 nonblocking(&amp;lt;=) 을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;래치(latch) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;값을 저장할 수 있는 소자 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;가장 간단한 래치는 NOR 게이트 2개 또는 NAND 게이트 2개로 만들 수 있음 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;NAND 게이트가 NOR 게이트보다 레이아웃 크기가 작기 때문에 NAND 게이트로 만든 래치를 주로 설명&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clgzaQ/btsO8icg2iF/7BhAEI6HcobFcm5I55wLD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clgzaQ/btsO8icg2iF/7BhAEI6HcobFcm5I55wLD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clgzaQ/btsO8icg2iF/7BhAEI6HcobFcm5I55wLD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclgzaQ%2FbtsO8icg2iF%2F7BhAEI6HcobFcm5I55wLD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;214&quot; height=&quot;137&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;137&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SR래치의 동작&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cvzsu/btsO6xhxzoM/K62sDHeMSAtqd6eUqqZlc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cvzsu/btsO6xhxzoM/K62sDHeMSAtqd6eUqqZlc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cvzsu/btsO6xhxzoM/K62sDHeMSAtqd6eUqqZlc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCvzsu%2FbtsO6xhxzoM%2FK62sDHeMSAtqd6eUqqZlc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;344&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SR래치의 파형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S와 R신호는 active-low 신호로 생각한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCzm9E/btsO67CI7PI/J8kRFv8JffHq6KvKO7wpI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCzm9E/btsO67CI7PI/J8kRFv8JffHq6KvKO7wpI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCzm9E/btsO67CI7PI/J8kRFv8JffHq6KvKO7wpI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCzm9E%2FbtsO67CI7PI%2FJ8kRFv8JffHq6KvKO7wpI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;307&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S=0, R=0으로 모두 active 된 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 다시 S=0, R=0이 되었을 때 set이 될 지 reset이 될 지 모름 &lt;br /&gt;&amp;rarr; &amp;nbsp;이러한 값이 입력되지 않도록 해야 함&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s2bRl/btsO8owLgzd/ZuZnV5aaXa4lJv4DaQYmzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s2bRl/btsO8owLgzd/ZuZnV5aaXa4lJv4DaQYmzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s2bRl/btsO8owLgzd/ZuZnV5aaXa4lJv4DaQYmzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs2bRl%2FbtsO8owLgzd%2FZuZnV5aaXa4lJv4DaQYmzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;335&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SR래치의 상태표(state table)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;318&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj2gCo/btsO8c4qRmI/2n19DrmXfwHUTmcV4Jgm3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj2gCo/btsO8c4qRmI/2n19DrmXfwHUTmcV4Jgm3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj2gCo/btsO8c4qRmI/2n19DrmXfwHUTmcV4Jgm3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj2gCo%2FbtsO8c4qRmI%2F2n19DrmXfwHUTmcV4Jgm3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;318&quot; height=&quot;169&quot; data-origin-width=&quot;318&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0krfL/btsO6XmW2qY/gKbWcVCOaKVYcEOcehcBw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0krfL/btsO6XmW2qY/gKbWcVCOaKVYcEOcehcBw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0krfL/btsO6XmW2qY/gKbWcVCOaKVYcEOcehcBw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0krfL%2FbtsO6XmW2qY%2FgKbWcVCOaKVYcEOcehcBw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;129&quot; height=&quot;109&quot; data-origin-width=&quot;129&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적으로 가장 많이 사용되는 Latch&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YskZg/btsO6045TM6/xpeN8k1wI0g1DJR9ZJYXTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YskZg/btsO6045TM6/xpeN8k1wI0g1DJR9ZJYXTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YskZg/btsO6045TM6/xpeN8k1wI0g1DJR9ZJYXTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYskZg%2FbtsO6045TM6%2FxpeN8k1wI0g1DJR9ZJYXTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;220&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDlOS6/btsO6CwBosj/ZQ6K688y1xvkaJSLk2sPT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDlOS6/btsO6CwBosj/ZQ6K688y1xvkaJSLk2sPT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDlOS6/btsO6CwBosj/ZQ6K688y1xvkaJSLk2sPT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDlOS6%2FbtsO6CwBosj%2FZQ6K688y1xvkaJSLk2sPT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;131&quot; height=&quot;108&quot; data-origin-width=&quot;131&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch의 상태표&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brnNc4/btsO8nEDWVD/fdthuw0Bd0NZd3NeqkNwH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brnNc4/btsO8nEDWVD/fdthuw0Bd0NZd3NeqkNwH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brnNc4/btsO8nEDWVD/fdthuw0Bd0NZd3NeqkNwH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrnNc4%2FbtsO8nEDWVD%2Ffdthuw0Bd0NZd3NeqkNwH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;321&quot; height=&quot;148&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dr5lEz/btsO8mFJVYj/R6BJdxF8le8S5QmYHTgNOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dr5lEz/btsO8mFJVYj/R6BJdxF8le8S5QmYHTgNOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dr5lEz/btsO8mFJVYj/R6BJdxF8le8S5QmYHTgNOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdr5lEz%2FbtsO8mFJVYj%2FR6BJdxF8le8S5QmYHTgNOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;177&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch의 파형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EN = 1일 때 Q는 입력 D를 그대로 출력하므로 transparent latch라고도 함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl8KLP/btsO7oEimRL/JPuyS1xSUaNb4H2SvmWBjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl8KLP/btsO7oEimRL/JPuyS1xSUaNb4H2SvmWBjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl8KLP/btsO7oEimRL/JPuyS1xSUaNb4H2SvmWBjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl8KLP%2FbtsO7oEimRL%2FJPuyS1xSUaNb4H2SvmWBjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;298&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Cross-coupled&amp;nbsp;inverter &lt;br /&gt;- Cross-coupled inverter는 bi-stable 회로로 2가지의 값을 안정적으로 저장 &lt;br /&gt;- SR latch도 cross-coupled inverter를 기본으로 하고 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbyATr/btsO78VomvI/sAyK1PqzVdLTj4uYLGnBjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbyATr/btsO78VomvI/sAyK1PqzVdLTj4uYLGnBjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbyATr/btsO78VomvI/sAyK1PqzVdLTj4uYLGnBjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbyATr%2FbtsO78VomvI%2FsAyK1PqzVdLTj4uYLGnBjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;304&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cross-coupled&amp;nbsp;inverter &lt;br /&gt;- Vi1=Vo2=1, Vi2=Vo1=0 또는 Vi1=Vo2=0, Vi2=Vo1=1 일 때 안정된 상태&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xCyat/btsO6AZLxMR/oDjD3EwKeQ4rBcRgDmTn6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xCyat/btsO6AZLxMR/oDjD3EwKeQ4rBcRgDmTn6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xCyat/btsO6AZLxMR/oDjD3EwKeQ4rBcRgDmTn6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxCyat%2FbtsO6AZLxMR%2FoDjD3EwKeQ4rBcRgDmTn6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;277&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D&amp;nbsp;latch &lt;br /&gt;- Cross-coupled inverter와 transmission gate 2개를 사용하여 만들 수 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ePAQHy/btsO7RzKf62/gDzRoWO9atA8CrrD8YcuG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ePAQHy/btsO7RzKf62/gDzRoWO9atA8CrrD8YcuG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ePAQHy/btsO7RzKf62/gDzRoWO9atA8CrrD8YcuG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FePAQHy%2FbtsO7RzKf62%2FgDzRoWO9atA8CrrD8YcuG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;257&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch의 동작&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MK0Ih/btsO8KTTNT2/taeDrV2iMBmm2FSaSBzek1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MK0Ih/btsO8KTTNT2/taeDrV2iMBmm2FSaSBzek1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MK0Ih/btsO8KTTNT2/taeDrV2iMBmm2FSaSBzek1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMK0Ih%2FbtsO8KTTNT2%2FtaeDrV2iMBmm2FSaSBzek1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;363&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;래치(latch)의&amp;nbsp;사용 &lt;br /&gt;- 래치를 사용하여 회로를 꾸밀 때에는 주로 two phase non-overlapping clock 등을 사용 &lt;br /&gt;- 그러나 클럭 스큐 등의 문제가 있어 회로가 복잡해지면 사용이 쉽지 않음 &lt;br /&gt;- 오히려 래치는 만들지 말아야 할 것으로 인식됨 &lt;br /&gt;- Verilog 사용자가 조합회로를 만들었으나 실수를 하여 래치가 만들어지는 경우가 발생 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;rarr; 이를 방지하기 위해서는 모든 입력의 경우의 수에 대하여 출력을 명시하면 됨 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;rarr; 모든 경우에 대하여 명시가 어렵다면 상황에 따라 default 문장, else 문장, 출력 초기화를 사용 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;rarr; 기타 방법으로 &amp;ldquo;full_case parallel_case&amp;rdquo;를 사용하는 방법이 있으나 권장되지는 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clock&amp;nbsp;신호 &lt;br /&gt;- Clock 신호는 주기적인 square wave 임 &lt;br /&gt;- Clock 신호는 의미있는 정보를 보낸다기 보다는 타이밍을 맞추기 위해 사용 &lt;br /&gt;- Clock에 맞추어 Latch 또는 플립플롭들이 동시에 정보를 저장&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwltoG/btsO67XdNNC/tijSChyYFFFwAPkAe6q4O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwltoG/btsO67XdNNC/tijSChyYFFFwAPkAe6q4O0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwltoG/btsO67XdNNC/tijSChyYFFFwAPkAe6q4O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwltoG%2FbtsO67XdNNC%2FtijSChyYFFFwAPkAe6q4O0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;105&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플립플롭&amp;nbsp;개요 &lt;br /&gt;- 플립플롭(F/F)은 Clock 신호가 변화(transition)하는 시점인 edge(에지)에 맞추어 동작 (Edge-sensitive) (Latch는 Clock 신호 값의 수준에 맞추어 동작 (Level-sensitive)) &lt;br /&gt;- Rising edge에 맞추어 동작하는 F/F을 rising edge triggered F/F 이라 함 &lt;br /&gt;- Falling edge에 맞추어 동작하는 F/F을 falling edge triggered F/F 이라 함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWHGez/btsO8HbWn49/U0IF7dRdx5dBcglfJPs6Jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWHGez/btsO8HbWn49/U0IF7dRdx5dBcglfJPs6Jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWHGez/btsO8HbWn49/U0IF7dRdx5dBcglfJPs6Jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWHGez%2FbtsO8HbWn49%2FU0IF7dRdx5dBcglfJPs6Jk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;302&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Classical&amp;nbsp;D&amp;nbsp;F/F &lt;br /&gt;- 전통적인 구조의 rising edge-triggered D F/F &lt;br /&gt;- C=0 이면 S=1와 R=1이므로 Q와 Q는 값을 유지 &lt;br /&gt;- C=0 에서 C=1이 되고 이 때 D=0이라면 오른쪽 SR래치에 S=1, R=0이 입력되어 Q=0이 됨 &lt;br /&gt;- 따라서 C=0에서 C=1이 되는 순간(rising edge)에 D=0의 값을 받아 Q=0이 됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sPJZA/btsO7OC12bH/LbaCHq0GbL2ktpYmXKIKx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sPJZA/btsO7OC12bH/LbaCHq0GbL2ktpYmXKIKx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sPJZA/btsO7OC12bH/LbaCHq0GbL2ktpYmXKIKx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsPJZA%2FbtsO7OC12bH%2FLbaCHq0GbL2ktpYmXKIKx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;216&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Classical&amp;nbsp;D&amp;nbsp;F/F &lt;br /&gt;- C=0 이면 S=1와 R=1이므로 Q와 Q는 값을 유지 &lt;br /&gt;- C=0 에서 C=1이 되고 이 때 D=1이라면 오른쪽 SR래치에 S=0, R=1이 입력되어 Q=1이 됨 &lt;br /&gt;- 따라서 C=0에서 C=1이 되는 순간(rising edge)에 D=1의 값을 받아 Q=1이 됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNe0Ka/btsO8CaKofF/pwJ1autT7wTwFHd0LkVZA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNe0Ka/btsO8CaKofF/pwJ1autT7wTwFHd0LkVZA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNe0Ka/btsO8CaKofF/pwJ1autT7wTwFHd0LkVZA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNe0Ka%2FbtsO8CaKofF%2FpwJ1autT7wTwFHd0LkVZA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;203&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D F/F 상태표&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oYSbe/btsO6EuzZtd/A8GxkzkpuqH789XMcSlpWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oYSbe/btsO6EuzZtd/A8GxkzkpuqH789XMcSlpWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oYSbe/btsO6EuzZtd/A8GxkzkpuqH789XMcSlpWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoYSbe%2FbtsO6EuzZtd%2FA8GxkzkpuqH789XMcSlpWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;333&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Edge-triggered&amp;nbsp;D&amp;nbsp;F/F &lt;br /&gt;- Edge-triggered D F/F = Pulse transition detector + D Latch &lt;br /&gt;- Pulse transition detector가 아주 짧은 시간만 D latch의 EN=1로 하므로 마치 edge에 값을 받아들이는 동작의&amp;nbsp;효과를&amp;nbsp;냄&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vWG1t/btsO6Ar3Pk3/GP76CxWym0TIkZk1iDmV6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vWG1t/btsO6Ar3Pk3/GP76CxWym0TIkZk1iDmV6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vWG1t/btsO6Ar3Pk3/GP76CxWym0TIkZk1iDmV6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvWG1t%2FbtsO6Ar3Pk3%2FGP76CxWym0TIkZk1iDmV6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;310&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pulse&amp;nbsp;transition&amp;nbsp;detector&amp;nbsp;회로 &lt;br /&gt;- 신호가 inverter를 통과할 때의 지연시간을 이용하여 짧은 시간 동안만 1이 되는 일종의 glitch(spike)를 발생시킴&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf4iQK/btsO6NSd2D4/yGFSWYXzeqwJsopFkkqzrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf4iQK/btsO6NSd2D4/yGFSWYXzeqwJsopFkkqzrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf4iQK/btsO6NSd2D4/yGFSWYXzeqwJsopFkkqzrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf4iQK%2FbtsO6NSd2D4%2FyGFSWYXzeqwJsopFkkqzrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;312&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Master-slave&amp;nbsp;D&amp;nbsp;F/F &lt;br /&gt;- 앞의 2가지 D F/F과 동작이 같음 &lt;br /&gt;- 2개의 D latch를 사용하여 구성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/laZho/btsO7IvTA6M/YvQI4boeFRVwm4ZNzrUc7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/laZho/btsO7IvTA6M/YvQI4boeFRVwm4ZNzrUc7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/laZho/btsO7IvTA6M/YvQI4boeFRVwm4ZNzrUc7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlaZho%2FbtsO7IvTA6M%2FYvQI4boeFRVwm4ZNzrUc7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;347&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Master-slave D F/F (회로의 다른 표현)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/27yBJ/btsO7oYI2jF/mNV1Js7zrKaYxH9Crw4xc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/27yBJ/btsO7oYI2jF/mNV1Js7zrKaYxH9Crw4xc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/27yBJ/btsO7oYI2jF/mNV1Js7zrKaYxH9Crw4xc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F27yBJ%2FbtsO7oYI2jF%2FmNV1Js7zrKaYxH9Crw4xc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;384&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mater-slave D F/F의 동작 매커니즘&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dd9Vci/btsO7RsXL16/b8FUEReYcjwAT2dFxUYNr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dd9Vci/btsO7RsXL16/b8FUEReYcjwAT2dFxUYNr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dd9Vci/btsO7RsXL16/b8FUEReYcjwAT2dFxUYNr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdd9Vci%2FbtsO7RsXL16%2Fb8FUEReYcjwAT2dFxUYNr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;534&quot; height=&quot;421&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기&amp;nbsp;리셋&amp;nbsp;D&amp;nbsp;F/F &lt;br /&gt;- 동기(Synchronous) : 클럭 신호에 맞추어 값이 변할 경우 &lt;br /&gt;- 비동기(Asynchronous) : 클럭 신호와 상관없이 값이 변할 경우&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lx4Bg/btsO7oYI7MF/7peYdtBY58Gbg8UzcIZvRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lx4Bg/btsO7oYI7MF/7peYdtBY58Gbg8UzcIZvRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lx4Bg/btsO7oYI7MF/7peYdtBY58Gbg8UzcIZvRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flx4Bg%2FbtsO7oYI7MF%2F7peYdtBY58Gbg8UzcIZvRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;231&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 리셋 D F/F의 상태표&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uxp2Y/btsO8FrESWn/f6xWlPrJdHF5Uo5Y4PmCPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uxp2Y/btsO8FrESWn/f6xWlPrJdHF5Uo5Y4PmCPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uxp2Y/btsO8FrESWn/f6xWlPrJdHF5Uo5Y4PmCPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuxp2Y%2FbtsO8FrESWn%2Ff6xWlPrJdHF5Uo5Y4PmCPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;521&quot; height=&quot;384&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch와 D F/F의 파형&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRd32u/btsO6MsdR1f/Rury1sLOTghp91zCMMsv4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRd32u/btsO6MsdR1f/Rury1sLOTghp91zCMMsv4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRd32u/btsO6MsdR1f/Rury1sLOTghp91zCMMsv4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRd32u%2FbtsO6MsdR1f%2FRury1sLOTghp91zCMMsv4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;386&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Propagation&amp;nbsp;delay&amp;nbsp;time,&amp;nbsp;전달(전파)&amp;nbsp;지연&amp;nbsp;시간 &lt;br /&gt;- Tclk-q : Clock의 edge로부터 값이 출력되기까지의 시간&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJGxy3/btsO6KHZQcT/5WBZz0a87ySC1jlRkmlgQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJGxy3/btsO6KHZQcT/5WBZz0a87ySC1jlRkmlgQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJGxy3/btsO6KHZQcT/5WBZz0a87ySC1jlRkmlgQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJGxy3%2FbtsO6KHZQcT%2F5WBZz0a87ySC1jlRkmlgQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;309&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D Latch와 D F/F의 차이점&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FVJjP/btsO764t9wR/DRwt8l5aC36ykEaJijftPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FVJjP/btsO764t9wR/DRwt8l5aC36ykEaJijftPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FVJjP/btsO764t9wR/DRwt8l5aC36ykEaJijftPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFVJjP%2FbtsO764t9wR%2FDRwt8l5aC36ykEaJijftPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;422&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F/F&amp;nbsp;타이밍&amp;nbsp;고찰 &lt;br /&gt;- 실제로는 tclk-to-q 지연시간 때문에 q1, q0가 clock edge 보다 늦게 변하므로 clock edge 기준 앞의 값을 받아들이는 것으로 생각한다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rzxWY/btsO7GERhYf/zJDlHFMr4JXPDAf0bkcMR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rzxWY/btsO7GERhYf/zJDlHFMr4JXPDAf0bkcMR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rzxWY/btsO7GERhYf/zJDlHFMr4JXPDAf0bkcMR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrzxWY%2FbtsO7GERhYf%2FzJDlHFMr4JXPDAf0bkcMR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;364&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터 회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbHewP/btsO8JUZXlf/Uktm13DpDf2ampTMNGIeE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbHewP/btsO8JUZXlf/Uktm13DpDf2ampTMNGIeE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbHewP/btsO8JUZXlf/Uktm13DpDf2ampTMNGIeE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbHewP%2FbtsO8JUZXlf%2FUktm13DpDf2ampTMNGIeE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;125&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이프라인(Pipeline) 형태의 회로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2HrDi/btsO8qnZlvu/KADQrggrwotPmRgAlUbYv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2HrDi/btsO8qnZlvu/KADQrggrwotPmRgAlUbYv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2HrDi/btsO8qnZlvu/KADQrggrwotPmRgAlUbYv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2HrDi%2FbtsO8qnZlvu%2FKADQrggrwotPmRgAlUbYv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;401&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F/F의&amp;nbsp;셋업(setup)과&amp;nbsp;홀드(hold)&amp;nbsp;시간 &lt;br /&gt;- Setup time : Clock의 edge 전 미리 입력 데이터가 안정되어야 하는 최소 시간 &lt;br /&gt;- Hold time : Clock의 edge 후 입력 데이터가 유지되고 있어야 하는 최소 시간&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3XGVJ/btsO7ytDVSb/DU8rjMqv7uQ5naGpcRwB30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3XGVJ/btsO7ytDVSb/DU8rjMqv7uQ5naGpcRwB30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3XGVJ/btsO7ytDVSb/DU8rjMqv7uQ5naGpcRwB30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3XGVJ%2FbtsO7ytDVSb%2FDU8rjMqv7uQ5naGpcRwB30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;231&quot; height=&quot;188&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유한상태&amp;nbsp;머신(Finite&amp;nbsp;State&amp;nbsp;Machine;&amp;nbsp;FSM) &lt;br /&gt;- 지정된 수의 상태를 가지고 상태의 천이에 의해 출력을 생성하는 회로 &lt;br /&gt;- 디지털 시스템의 제어회로 구성에 사용 &lt;br /&gt;- Moore 머신 : 출력이 현재상태에 의해서만 결정 &lt;br /&gt;- Mealy 머신 : 출력이 현재상태와 입력에 의해 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9V5xz/btsO6ZSVmA7/Lo22dPkFt1UQ6RYYDsiwvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9V5xz/btsO6ZSVmA7/Lo22dPkFt1UQ6RYYDsiwvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9V5xz/btsO6ZSVmA7/Lo22dPkFt1UQ6RYYDsiwvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9V5xz%2FbtsO6ZSVmA7%2FLo22dPkFt1UQ6RYYDsiwvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;673&quot; height=&quot;177&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mealy FSM&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/puH9W/btsO8F6qhPh/lnvDNpDlUVBdxpxyjpujZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/puH9W/btsO8F6qhPh/lnvDNpDlUVBdxpxyjpujZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/puH9W/btsO8F6qhPh/lnvDNpDlUVBdxpxyjpujZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpuH9W%2FbtsO8F6qhPh%2FlnvDNpDlUVBdxpxyjpujZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;267&quot; height=&quot;350&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fsm.v&lt;/p&gt;
&lt;pre id=&quot;code_1751875820636&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module fsm (
    input  wire clk,
    input  wire rstn,
    input  wire done,
    output ack,
    output reg [1:0] current_state  // 상태를 외부에서도 관찰 가능하게
);

    // 상태 인코딩 정의
    parameter READY = 2'b00;
    parameter TRANS = 2'b01;
    parameter WRITE = 2'b10;
    parameter READ  = 2'b11;

    reg [1:0] next_state;

    // 순차 논리: 상태 전이
    always @(posedge clk or negedge rstn) begin
        if (!rstn)
            current_state &amp;lt;= READY;
        else
            current_state &amp;lt;= next_state;
    end

    // 조합 논리: next state 계산
    always @(current_state or done) begin
        case (current_state)
            READY:  next_state = (done == 1) ? TRANS : READY;
            TRANS:  next_state = (done == 0) ? TRANS : WRITE;
            WRITE:  next_state = (done == 1) ? READ  : WRITE;
            READ:   next_state = (done == 0) ? READ  : READY;
            default: next_state = READY;
        endcase
    end

    assign ack = 1;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tb_fsm.v&lt;/p&gt;
&lt;pre id=&quot;code_1751875832243&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module tb_fsm();

    reg clk, rstn;
    reg done;
    wire ack;
    wire [1:0] current_state;

    // ✅ 모듈 이름 일치시키기 (fsm)
    fsm dut_fsm (
        .clk(clk), 
        .rstn(rstn), 
        .done(done), 
        .ack(ack),
        .current_state(current_state)
    );

    // 클럭 생성
    initial clk = 0;
    always #5 clk = ~clk;  // 10ns 주기

    // 테스트 시나리오
    initial begin
        // 파형 출력
        $dumpfile(&quot;fsm_tb.vcd&quot;);
        $dumpvars(0, tb_fsm);

        // 초기 조건
        rstn = 0; done = 0;

        // 리셋 &amp;rarr; READY
        #20 rstn = 1;

        // 상태 전이 시퀀스
        #10 done = 0; // READY, ack = 1
        #10 done = 1; // TRANS, ack = 1
        #10 done = 1; // TRANS 유지
        #10 done = 0; // WRITE
        #10 done = 0; // WRITE 유지
        #10 done = 1; // READ
        #10 done = 0; // READ 유지
        #10 done = 1; // READY
        #10 done = 0; // READY
        #10 done = 1; // TRANS
        #10 rstn = 0; // 다시 RESET
        #10 rstn = 1; // RESET OFF

        #20 $finish;
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDmjTt/btsO6YTZRzs/ot2YqZLVDFywLgxEy6PNf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDmjTt/btsO6YTZRzs/ot2YqZLVDFywLgxEy6PNf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDmjTt/btsO6YTZRzs/ot2YqZLVDFywLgxEy6PNf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDmjTt%2FbtsO6YTZRzs%2Fot2YqZLVDFywLgxEy6PNf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1056&quot; height=&quot;297&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Moore FSM&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tc6EY/btsO7pcnSsU/mKcRVGia8gM4JFs6yHkQxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tc6EY/btsO7pcnSsU/mKcRVGia8gM4JFs6yHkQxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tc6EY/btsO7pcnSsU/mKcRVGia8gM4JFs6yHkQxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftc6EY%2FbtsO7pcnSsU%2FmKcRVGia8gM4JFs6yHkQxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;193&quot; height=&quot;309&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;moore_fsm.v&lt;/p&gt;
&lt;pre id=&quot;code_1751876473686&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module fsm_moore (
    input  wire clk,
    input  wire rstn,
    input  wire done,
    output reg ack,                      // reg로 변경 (Moore는 상태 기반 출력)
    output reg [1:0] current_state       // 상태 관찰용 출력
);

    // 상태 인코딩
    parameter READY = 2'b00;
    parameter TRANS = 2'b01;
    parameter WRITE = 2'b10;
    parameter READ  = 2'b11;

    reg [1:0] next_state;

    // 상태 전이 (순차 논리)
    always @(posedge clk or negedge rstn) begin
        if (!rstn)
            current_state &amp;lt;= READY;
        else
            current_state &amp;lt;= next_state;
    end

    // 다음 상태 결정 (조합 논리)
    always @(*) begin
        case (current_state)
            READY:  next_state = (done) ? TRANS : READY;
            TRANS:  next_state = (done) ? WRITE : TRANS;
            WRITE:  next_state = (done) ? READ  : WRITE;
            READ:   next_state = (done) ? READY : READ;
            default: next_state = READY;
        endcase
    end

    // Moore 출력 로직: 상태에 따라 출력 결정
    always @(*) begin
        case (current_state)
            READY:  ack = 1'b0;
            TRANS:  ack = 1'b0;
            WRITE:  ack = 1'b0;
            READ:   ack = 1'b1;   // 예: READ 상태일 때만 ack=1
            default: ack = 1'b0;
        endcase
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tb_moore_fsm.v&lt;/p&gt;
&lt;pre id=&quot;code_1751876483053&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module tb_fsm_moore();

    reg clk, rstn;
    reg done;
    wire ack;
    wire [1:0] current_state;

    // ✅ Moore FSM DUT 인스턴스
    fsm_moore dut (
        .clk(clk),
        .rstn(rstn),
        .done(done),
        .ack(ack),
        .current_state(current_state)
    );

    // ✅ 클럭 생성: 10ns 주기 (100MHz)
    initial clk = 0;
    always #5 clk = ~clk;

    // ✅ 시뮬레이션 시나리오
    initial begin
        $dumpfile(&quot;fsm_moore_tb.vcd&quot;);  // 파형 저장 파일
        $dumpvars(0, tb_fsm_moore);

        // 초기값
        rstn = 0;
        done = 0;

        // 리셋 해제
        #20 rstn = 1;

        // 상태 전이 순서 (Moore FSM 기준)
        #10 done = 0; // READY 유지
        #10 done = 1; // TRANS로 전이
        #10 done = 1; // WRITE로 전이
        #10 done = 1; // READ로 전이
        #10 done = 1; // READY로 전이
        #10 done = 1; // TRANS로 전이
        #10 done = 0; // TRANS 유지
        #10 done = 1; // WRITE로 전이
        #10 done = 1; // READ로 전이
        #10 done = 0; // READ 유지
        #10 done = 1; // READY로 전이

        // 리셋 테스트
        #10 rstn = 0;
        #10 rstn = 1;
        #20 done = 0;

        #20 $finish;
    end

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMetbo/btsO6Z6vp7I/MufmTFhvYaawk906wkmgIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMetbo/btsO6Z6vp7I/MufmTFhvYaawk906wkmgIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMetbo/btsO6Z6vp7I/MufmTFhvYaawk906wkmgIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMetbo%2FbtsO6Z6vp7I%2FMufmTFhvYaawk906wkmgIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1056&quot; height=&quot;296&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/533</guid>
      <comments>https://hotari.tistory.com/533#entry533comment</comments>
      <pubDate>Mon, 7 Jul 2025 17:49:29 +0900</pubDate>
    </item>
    <item>
      <title>5일차 mini Project1 - MINSEC_WATCH/STOPWATCH</title>
      <link>https://hotari.tistory.com/532</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;목적 &lt;br /&gt;Basys3 (100 MHz) FPGA 보드 위에 4자리 7-세그먼트(FND)를 장착한 디지털 인터페이스 구현 &lt;br /&gt;&lt;br /&gt;사용자 버튼 조작으로 3가지 동작 모드 전환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDLE (CIRCLE 회전) &lt;br /&gt;MINSEC_WATCH (분&amp;middot;초 시계) &lt;br /&gt;STOPWATCH (스톱워치) &lt;br /&gt;&lt;br /&gt;입력&amp;nbsp;BTN[3:0] &lt;br /&gt;BTN[0]: 모드 전환(IDLE &amp;rarr; WATCH &amp;rarr; STOPWATCH &amp;rarr; IDLE) &lt;br /&gt;BTN[1]: 스톱워치 시작/정지 토글 &lt;br /&gt;BTN[2]: 스톱워치 초기화 &lt;br /&gt;BTN[3]: IDLE 모드 시 회전 속도 변경 &lt;br /&gt;RESET: 모든 모드에서 IDLE로 복귀 &lt;br /&gt;&lt;br /&gt;출력&amp;nbsp;FND[3:0]&amp;nbsp;+&amp;nbsp;SEG[6:0] &lt;br /&gt;4자리 7-세그먼트 디스플레이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;957&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HRFPA/btsO6dwFPp2/DM1dB2bIxllUmy3bSIkkR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HRFPA/btsO6dwFPp2/DM1dB2bIxllUmy3bSIkkR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HRFPA/btsO6dwFPp2/DM1dB2bIxllUmy3bSIkkR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHRFPA%2FbtsO6dwFPp2%2FDM1dB2bIxllUmy3bSIkkR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;648&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;957&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c23WX1/btsO6bllU3n/Fg1IIgxlfDRcmtVciKi9Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c23WX1/btsO6bllU3n/Fg1IIgxlfDRcmtVciKi9Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c23WX1/btsO6bllU3n/Fg1IIgxlfDRcmtVciKi9Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc23WX1%2FbtsO6bllU3n%2FFg1IIgxlfDRcmtVciKi9Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;939&quot; height=&quot;430&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1485&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1nP6y/btsO5OxaCZ3/vpiqfUZ4AZQHKgg2MRF99K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1nP6y/btsO5OxaCZ3/vpiqfUZ4AZQHKgg2MRF99K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1nP6y/btsO5OxaCZ3/vpiqfUZ4AZQHKgg2MRF99K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1nP6y%2FbtsO5OxaCZ3%2FvpiqfUZ4AZQHKgg2MRF99K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;747&quot; data-origin-width=&quot;1485&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/evlZQL/btsO6zMNgUD/Qhf8d3kMZqhDkShwyHKazK/btn_command_controller.v?attach=1&amp;amp;knm=tfile.v&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;btn_command_controller.v&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b5E38f/btsO7QfJmUR/G9VGRdfdnZrBesOV4LLG8K/fnd_controller.v?attach=1&amp;amp;knm=tfile.v&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;fnd_controller.v&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/W3FgC/btsO7oRetVd/vTlLKhRCFKn2GiKgn84PE0/minsec_stopwatch_top.v?attach=1&amp;amp;knm=tfile.v&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;minsec_stopwatch_top.v&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/05.minsec_stopwatch_project&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/05.minsec_stopwatch_project&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 영상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/3Lz6mxAgbA8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/3Lz6mxAgbA8&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/532</guid>
      <comments>https://hotari.tistory.com/532#entry532comment</comments>
      <pubDate>Mon, 7 Jul 2025 12:15:47 +0900</pubDate>
    </item>
    <item>
      <title>4일차</title>
      <link>https://hotari.tistory.com/531</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.03&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1981&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nF75a/btsO1x9j6co/WBg16DCKvIKJu8b5ZlMsSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nF75a/btsO1x9j6co/WBg16DCKvIKJu8b5ZlMsSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nF75a/btsO1x9j6co/WBg16DCKvIKJu8b5ZlMsSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnF75a%2FbtsO1x9j6co%2FWBg16DCKvIKJu8b5ZlMsSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1981&quot; height=&quot;675&quot; data-origin-width=&quot;1981&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdHv1X/btsO09ATd6N/k4ApKqkpuVRbYjm7yMI670/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdHv1X/btsO09ATd6N/k4ApKqkpuVRbYjm7yMI670/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdHv1X/btsO09ATd6N/k4ApKqkpuVRbYjm7yMI670/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdHv1X%2FbtsO09ATd6N%2Fk4ApKqkpuVRbYjm7yMI670%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;252&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;1175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mF462/btsO198z8Bx/olMhVUNzMMmE6ZHeMUJmM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mF462/btsO198z8Bx/olMhVUNzMMmE6ZHeMUJmM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mF462/btsO198z8Bx/olMhVUNzMMmE6ZHeMUJmM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmF462%2FbtsO198z8Bx%2FolMhVUNzMMmE6ZHeMUJmM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;590&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;1175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1027&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vHcZj/btsO1U4VCRx/uxAQctnKuLQbKRLkr3EtP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vHcZj/btsO1U4VCRx/uxAQctnKuLQbKRLkr3EtP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vHcZj/btsO1U4VCRx/uxAQctnKuLQbKRLkr3EtP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvHcZj%2FbtsO1U4VCRx%2FuxAQctnKuLQbKRLkr3EtP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2406&quot; height=&quot;1027&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1027&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1645&quot; data-origin-height=&quot;895&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zsBeM/btsO2W1p2cd/jeK0aMXO1cXc12tPvOjXa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zsBeM/btsO2W1p2cd/jeK0aMXO1cXc12tPvOjXa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zsBeM/btsO2W1p2cd/jeK0aMXO1cXc12tPvOjXa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzsBeM%2FbtsO2W1p2cd%2FjeK0aMXO1cXc12tPvOjXa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1645&quot; height=&quot;895&quot; data-origin-width=&quot;1645&quot; data-origin-height=&quot;895&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1qozw/btsO2FFC1U4/z3kBP7SigX9MmYQpXSCWMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1qozw/btsO2FFC1U4/z3kBP7SigX9MmYQpXSCWMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1qozw/btsO2FFC1U4/z3kBP7SigX9MmYQpXSCWMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1qozw%2FbtsO2FFC1U4%2Fz3kBP7SigX9MmYQpXSCWMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1233&quot; height=&quot;687&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fnd_controller.v&lt;/p&gt;
&lt;pre id=&quot;code_1751521917492&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module fnd_controller(
    input clk,
    input [13:0] input_data,
    input reset,
    output [3:0] an, // 자릿수 선택
    output [7:0] seg_data
    );

    wire [1:0] w_sel;

    fnd_digit_select u_fnd_digit_select(
        .clk(clk),
        .reset(reset),
        .sel(w_sel) // 00 01 10 11
    );

    wire [3:0] w_d1, w_d10, w_d100, w_d1000;

    bin2bcd u_bin2bcd(
        .in_data(input_data),
        .d1(w_d1),
        .d10(w_d10),
        .d100(w_d100),
        .d1000(w_d1000)
    );

    fnd_display u_fnd_display(
        .digit_sel(w_sel),
        .d1(w_d1),
        .d10(w_d10),
        .d100(w_d100),
        .d1000(w_d1000),
        .an(an),
        .seg(seg_data)
    );
endmodule


// 1ms마다 fnd를 display하기 위해 digit 1자리씩 선택
// 4ms까지는 잔상효과가 있다 그 이상이면 깜빡임 현상이 발생
module fnd_digit_select(
    input clk,
    input reset,
    output reg [1:0] sel // 00 01 10 11
);

    reg [16:0] r_1ms_counter = 0;
    reg [1:0] r_digit_sel = 0;

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            r_1ms_counter &amp;lt;= 0;
            r_digit_sel &amp;lt;= 0;
            sel &amp;lt;= 0;
        end else begin
            if (r_1ms_counter == 100_000-1) begin // 1ms
                r_1ms_counter &amp;lt;= 0;
                r_digit_sel &amp;lt;= r_digit_sel + 1;
                sel &amp;lt;= r_digit_sel;
            end else begin
                r_1ms_counter &amp;lt;= r_1ms_counter + 1;
            end
        end
    end
    
endmodule

// bin2bcd
// 입력 : bin 14bit인 이유 최대 9999까지 표현 값이 들어있기 때문
// 0 ~ 9999 
// 출력 : bcd
module bin2bcd (
    input [13:0] in_data,
    output [3:0] d1,
    output [3:0] d10,
    output [3:0] d100,
    output [3:0] d1000
);

    assign d1 = in_data % 10;
    assign d10 = (in_data / 10) % 10;
    assign d100 = (in_data / 100) % 10;
    assign d1000 = (in_data / 1000) % 10;
    
endmodule

module fnd_display (
    input [1:0] digit_sel,
    input [3:0] d1,
    input [3:0] d10,
    input [3:0] d100,
    input [3:0] d1000,
    output reg [3:0] an,
    output reg [7:0] seg
);

    reg [3:0] bcd_data;

    always @(digit_sel) begin
        case (digit_sel)
            2'b00: begin bcd_data = d1; an = 4'b1110; end
            2'b01: begin bcd_data = d10; an = 4'b1101; end
            2'b10: begin bcd_data = d100; an = 4'b1011; end
            2'b11: begin bcd_data = d1000; an = 4'b0011; end
            default: begin bcd_data = 4'b0000; an = 4'b1111; end
        endcase
    end

    always @(bcd_data) begin
        case (bcd_data)
            4'd0: seg &amp;lt;= 8'hC0; // 8'b11000000 : 0
            4'd1: seg &amp;lt;= 8'hF9; // 8'b11111001 : 1
            4'd2: seg &amp;lt;= 8'hA4; // 8'b10100100 : 2
            4'd3: seg &amp;lt;= 8'hB0; // 8'b10110000 : 3
            4'd4: seg &amp;lt;= 8'h99; // 8'b10011001 : 4
            4'd5: seg &amp;lt;= 8'h92; // 8'b10010010 : 5
            4'd6: seg &amp;lt;= 8'h82; // 8'b10000010 : 6
            4'd7: seg &amp;lt;= 8'hF8; // 8'b11111000 : 7
            4'd8: seg &amp;lt;= 8'h80; // 8'b10000000 : 8
            4'd9: seg &amp;lt;= 8'h90; // 8'b10010000 : 9
            default: seg = 8'hFF; // 8'b11111111 : all off
        endcase
    end
    
endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;top.v&lt;/p&gt;
&lt;pre id=&quot;code_1751521975416&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps

module top(
    input clk,
    input reset, // btnU
    input [2:0] btn,
    input [7:0] sw,
    output [7:0] seg,
    output [3:0] an,
    output [15:0] led
    );

    fnd_controller u_fnd_controller(
        .clk(clk),
        .input_data(15'd9999),
        .reset(reset),
        .an(an),
        .seg_data(seg)
    );

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCSSiz/btsO3xnsvcW/KiQQXZh3wIZfpbKkbP00K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCSSiz/btsO3xnsvcW/KiQQXZh3wIZfpbKkbP00K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCSSiz/btsO3xnsvcW/KiQQXZh3wIZfpbKkbP00K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCSSiz%2FbtsO3xnsvcW%2FKiQQXZh3wIZfpbKkbP00K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1223&quot; height=&quot;639&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/531</guid>
      <comments>https://hotari.tistory.com/531#entry531comment</comments>
      <pubDate>Fri, 4 Jul 2025 09:06:18 +0900</pubDate>
    </item>
    <item>
      <title>3일차</title>
      <link>https://hotari.tistory.com/530</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.02&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;button debounce&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FPGA의 버튼을 누를 때 단일 펄스만 생성하도록 Verilog에 간단한 디바운싱 회로를 구현&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sao3X/btsO0DOMIYR/pFEItz7A2HUhAqTMPlcT40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sao3X/btsO0DOMIYR/pFEItz7A2HUhAqTMPlcT40/img.png&quot; data-alt=&quot;FPGA의 버튼에 대한 디바운싱 회로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sao3X/btsO0DOMIYR/pFEItz7A2HUhAqTMPlcT40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSao3X%2FbtsO0DOMIYR%2FpFEItz7A2HUhAqTMPlcT40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;585&quot; height=&quot;375&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FPGA의 버튼에 대한 디바운싱 회로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100Mhz &amp;rarr; 8Hz&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100M / 8 = 12,500,000 cycles&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12,500,000 / 2 = 6,250,000 (10us * 62500개)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FPGA의 버튼을 눌렀다 놓으면 푸시 버튼 신호에서 예기치 않은 위아래 바운스가 많이 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바운싱 회로는 예상대로 바운싱 없이 CLOCK 기간을 가진 단일 pulse만 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wR8wI/btsOZhTQqNu/x6KIb6p2ZINkWtwgMT4Cd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wR8wI/btsOZhTQqNu/x6KIb6p2ZINkWtwgMT4Cd1/img.png&quot; data-alt=&quot;디바운싱 회로의 예상 파형&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wR8wI/btsOZhTQqNu/x6KIb6p2ZINkWtwgMT4Cd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwR8wI%2FbtsOZhTQqNu%2Fx6KIb6p2ZINkWtwgMT4Cd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;321&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디바운싱 회로의 예상 파형&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rD7Xw/btsO0bFiuEl/U0OaTbMk93C6lCkqfWeMoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rD7Xw/btsO0bFiuEl/U0OaTbMk93C6lCkqfWeMoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rD7Xw/btsO0bFiuEl/U0OaTbMk93C6lCkqfWeMoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrD7Xw%2FbtsO0bFiuEl%2FU0OaTbMk93C6lCkqfWeMoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;282&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;btnC를 1번 눌렀다 떼면 led가 on &amp;harr; off toggle&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YHi7s/btsO0hysniy/gN30YeQdIpMVeAXkUmDAv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YHi7s/btsO0hysniy/gN30YeQdIpMVeAXkUmDAv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YHi7s/btsO0hysniy/gN30YeQdIpMVeAXkUmDAv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYHi7s%2FbtsO0hysniy%2FgN30YeQdIpMVeAXkUmDAv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;614&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Debouncer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼 등의 스위치를 누르면 노이즈가 있는 신호가 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Debouncer : 기계적 진동 때문에 1이나 0으로 안정된 값을 바로 갖지 못하므로 이러한 채터(chatter) 또는 바운스(bounce)를 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값이 바뀔 때 여러 번 진동하므로 일정 시간 동안 값이 바뀌지 않는 경우 안정된 값으로 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스위치에 따라서 다르지만 보통은 10ms 정도 값이 바뀌지 않으면 값이 안정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 신호 in이 0에서 1로 바뀔 때 1의 값이 10ms 동안 바뀌지 않으면 out을 1로 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 반대의 경우도 마찬가지로 1에서 0으로 바뀔 때 in이 10ms동안 0을 유지한다면 out을 0으로 출력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czz7ba/btsO0KtEIMQ/s9hzYfiIU5ZGKk7MW49p01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czz7ba/btsO0KtEIMQ/s9hzYfiIU5ZGKk7MW49p01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czz7ba/btsO0KtEIMQ/s9hzYfiIU5ZGKk7MW49p01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczz7ba%2FbtsO0KtEIMQ%2Fs9hzYfiIU5ZGKk7MW49p01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;172&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/03.btn_debounce&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/SE0NGH0/AI_Verilog_HDL/tree/main/03.btn_debounce&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bD9iWC/btsO0U5dvMe/s4kTVk1LnUYJlRo3cCx0Wk/0702%20verilog%20%EA%B3%BC%EC%A0%9C%20%EB%B0%95%EC%84%B1%ED%98%B8.pptx?attach=1&amp;amp;knm=tfile.pptx&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;0702 verilog 과제 박성호.pptx&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;6.13MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/530</guid>
      <comments>https://hotari.tistory.com/530#entry530comment</comments>
      <pubDate>Wed, 2 Jul 2025 18:47:23 +0900</pubDate>
    </item>
    <item>
      <title>2일차</title>
      <link>https://hotari.tistory.com/529</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.07.01&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접으로 인한 수업 미참여&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/529</guid>
      <comments>https://hotari.tistory.com/529#entry529comment</comments>
      <pubDate>Wed, 2 Jul 2025 08:51:16 +0900</pubDate>
    </item>
    <item>
      <title>1일차</title>
      <link>https://hotari.tistory.com/528</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.30&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lmUqu/btsOWd4rzrf/ClY18zsUvw0ShkfPbkZQWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lmUqu/btsOWd4rzrf/ClY18zsUvw0ShkfPbkZQWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lmUqu/btsOWd4rzrf/ClY18zsUvw0ShkfPbkZQWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlmUqu%2FbtsOWd4rzrf%2FClY18zsUvw0ShkfPbkZQWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;261&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 대해서 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 모두 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Xilinx&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Fiel&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Programmable Gate Array) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발을 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위해 제공하는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도구&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 도구의 주요 사용 용도와 차이는 다음과 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;같다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Xilinx&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디자인 및 논리 합성 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도구&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 도구를 사용하면 디자인을 직접 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 구현하고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;논리를 합성하며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;타이밍 분석을 수행하고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 물리적 배치를 정의할 수 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, RTL(RTL, Register Transfer Level) &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설계를 위한 하드웨어 설명 언어&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;VHDL&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이나 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Verilog&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하여 사용자가 직접 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;하드웨어 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;로직을&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;설계 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;할 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;수 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Xilinx&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 소프트웨어 설계 스택으로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서 실행되는 애플리케이션을 개발하는 데 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 다양한 종류의 처리 요소&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: CPUs, GPUs, FPGAs)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 대해 단일 개발 환경을 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제공&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소프트웨어 개발자가 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;C, C++, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;OpenCL&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, Python &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;등의 고수준 언어를 사용하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 애플리케이션을 개발하고 최적화할 수 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 또한 라이브러리 세트를 제공하여 알고리즘을 빠르게 구현하고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기계 학습&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지 처리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 분석 등의 고수준 도메인에 대한 최적화를 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제공&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요약하면&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;는 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;의 하드웨어 설계 및 구현을 위한 도구이고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;는 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;에서 실행되는 소프트웨어 애플리케이션을 개발하는 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;도구&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;이&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 이 두 도구는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발의 다른 측면을 각각 다루며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종종 함께 사용되어 하드웨어와 소프트웨어를 모두 개발하는 통합 개발 환경을 제&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공합니다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;​​&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Xilinx &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Zynq&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Programmable Logic (PL)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Processing System (PS)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이라는 두 가지 주요 구성 요소가 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;span&gt;(1)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Programmable &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Logic (PL&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;): &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 주요 기능 중 하나로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자가 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특정 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로직&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 기능을 구현하기 위해 프로그래밍할 수 있는 &lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;영역이다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;PL &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;영역은 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;VHDL, Verilog &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;등의 하드웨어 설명 언어를 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;사용하여 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;구현되며&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;이는 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;와 같은 도구를 통해 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;수행된다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(2) Processing &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;System (&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS): &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Zynq&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FPGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 내장된 고정된 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하드웨어 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구성 요소로서&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적으로 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ARM &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;기반의 프로세서 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;시스템이다&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;. PS&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;는 운영 체제를 실행하고&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;소프트웨어 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;애플리케이션을 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;실행하며&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;, PL&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;과 상호 작용하는 데 &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;사용된다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 부분은 주로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고수준 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;언어&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(C, C++, Python &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;등&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하여 개발하며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 같은 도구를 통해 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;수행된다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 주로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PL&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;을 설계하고 구현하는 데 사용되며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서 실행되는 소프트웨어를 개발하는 데 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;두 시스템은 서로 밀접하게 연결되어 있으며&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종종 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vivado&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PL &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사이의 인터페이스를 설정하고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vitis&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서 실행되는 소프트웨어와 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PL&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서 실행되는 하드웨어 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로직&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 간의 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상호 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작용을 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관리한다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HDL : Hardware Description Language&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;디지털 논리 회로의 문자 표현&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- schematic보다 만들거나 고치기 쉬움&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- HDL 설계시에는 항상 schematic을 생각해야 함&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;HDL은 programming languages가 아님&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 매우 비슷하게 보이지만 프로그램처럼 작성하면 안됨&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Verilog 문법은 C와 상당히 유사함&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 뛰어넘어야 할 가장 중요하고 어려운 개념&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - C : 순차적 실행&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - HDL : 병렬적 실행&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 컴파일 방법은 비슷함&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - C : Source &amp;rarr; 컴파일 &amp;rarr; 실행파일&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - HDL : Source &amp;rarr; 컴파일 &amp;rarr; 시뮬레이션 &amp;rarr; 합성(synthesis)&amp;nbsp; &amp;rarr; Hardware&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgeyKW/btsOYgFrypu/Eh9hWPkdaEkjlxmMdAnNTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgeyKW/btsOYgFrypu/Eh9hWPkdaEkjlxmMdAnNTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgeyKW/btsOYgFrypu/Eh9hWPkdaEkjlxmMdAnNTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgeyKW%2FbtsOYgFrypu%2FEh9hWPkdaEkjlxmMdAnNTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;352&quot; height=&quot;384&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;208&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOU2rQ/btsOWbr76Wi/FGy8uBCGirhKxRzBTZsJp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOU2rQ/btsOWbr76Wi/FGy8uBCGirhKxRzBTZsJp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOU2rQ/btsOWbr76Wi/FGy8uBCGirhKxRzBTZsJp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOU2rQ%2FbtsOWbr76Wi%2FFGy8uBCGirhKxRzBTZsJp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;208&quot; height=&quot;143&quot; data-origin-width=&quot;208&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwbeTH/btsOWgsYDzb/PceNeONhFmAA5vXzuAcPt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwbeTH/btsOWgsYDzb/PceNeONhFmAA5vXzuAcPt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwbeTH/btsOWgsYDzb/PceNeONhFmAA5vXzuAcPt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwbeTH%2FbtsOWgsYDzb%2FPceNeONhFmAA5vXzuAcPt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;272&quot; height=&quot;218&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Verilog의 특징&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- C언어와 유사하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 코딩량이 10~30% 적다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회사에서는 Verilog가 우세하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 많은 IP들이 Verilog로 되어 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VHDL은 표현이 너무 엄격&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System IC 설계과정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUqxok/btsOVCwZWgY/hkKDkKqVchaSkb1VrGkUTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUqxok/btsOVCwZWgY/hkKDkKqVchaSkb1VrGkUTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUqxok/btsOVCwZWgY/hkKDkKqVchaSkb1VrGkUTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUqxok%2FbtsOVCwZWgY%2FhkKDkKqVchaSkb1VrGkUTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;347&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설계사양 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회로의 기능, 동작성능, 동작 주파수, 칩 면적 및 전력 소모 목표치, 시험 범주(test coverage), 설계 기간, NRE(Non-Recurring Engineering) 비용, 칩 단가 등이 포함된 설계 목표&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span&gt;설계될&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;시스템의&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;분할,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;적용될&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;알고리즘과&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;아키텍처,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;데이터&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;입/출력&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;제&lt;/span&gt;&lt;span&gt;어&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;신호들의&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;타이밍,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;입력/출력&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;신호의&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;이름과&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;비트&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;폭,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;리셋&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;신호&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;클록&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;신호에&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;대한&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;정의&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;등을&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;포함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;행위수준(Behavioral level) 모델링 및 검증&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 상세 설계 이전에 설계사양을 확인할 수 있도록 시스템의 전체기능을 모델링하고 검증하는 과정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 설계사양에서 정의된 기능의 만족 여부, 입/출력 인터페이스의 호환성, 국제표준규격의 만족 여부 등을 검증&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- C언어, Verilog, SystemVerilog, SystemC 등을 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;HDL 코딩 (RTL 설계)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RTL (Register Transfer Level) 모델링을 통한 상세 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 논리합성 툴에서 합성 가능한 코드로 개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 합성 가능한 RTL 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 모듈을 이용한 구조적 모델링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 합성이 지원되지 않는 구문이나 파일 입/출력 구문은 사용 금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 최적의 하드웨어가 합성되도록 모델링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 검증을 위한 테스트 벤치 (test bench) 작성&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HDL 시뮬레이션 (기능 검증)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RTL 모델이 설계사양을 만족하는지 확인하기 위한 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회로 내부의 지연이 고려되지 않은 기능 수준의 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회로의 기능을 정확하게 검증할 수 있는 테스트 벤치의 작성이 중요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 테스트벤치 작성은 설계자의 능력과 숙련도가 요구됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 최근 시스템 복잡도가 급격히 증가함에 따라 검증 작업이 설계 과정의 병목이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리합성 (synthesis)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RTL 수준의 HDL 코드를 게이트 수준의 논리회로로 변환하는 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 합성 조건들이 명시된 제한조건과 target library가 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Constraint&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 합성되는 회로의 목표 동작 주파수, 면적, 클록신호 사양, 입/출력 신호 사양, 환경 변수 및 설계 규칙 등 논리합성에 사용될 조건들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Target library&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 합성에 사용되는 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 특정 회사의 FPGA 디바이스 또는 특정 회사의 셀 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리합성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wNakK/btsOVJ93HPq/W6UGPrBzAosecLmMvw4R1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wNakK/btsOVJ93HPq/W6UGPrBzAosecLmMvw4R1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wNakK/btsOVJ93HPq/W6UGPrBzAosecLmMvw4R1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwNakK%2FbtsOVJ93HPq%2FW6UGPrBzAosecLmMvw4R1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;259&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리합성 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HDL 코드를 읽어 문법적인 오류를 분석하고 구문을 해석하여 논리 게이트로 변환하는 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 최적화 알고리즘을 적용하여 회로를 간소화시키는 최적화 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 셀 라이브러리로 매핑하는 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HEyet/btsOVdcI2HF/xhgWQnsKE9as5EvVDj53qK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HEyet/btsOVdcI2HF/xhgWQnsKE9as5EvVDj53qK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HEyet/btsOVdcI2HF/xhgWQnsKE9as5EvVDj53qK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHEyet%2FbtsOVdcI2HF%2FxhgWQnsKE9as5EvVDj53qK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;298&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게이트 수준 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 합성이 완려되면 게이트 수준의 netlist가 얻어지며 합성에 사용된 라이브러리의 특성이 합성된 회로에 반영됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RTL 수준 검증에서 사용되었던 테스트 벤치를 동일하게 적용하여 논리 및 타이밍을 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 정적 타이밍 분석 (Static Timing Analysis; STA)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 합성된 회로의 신호경로를 중심으로 타이밍을 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 시뮬레이션 벡터가 사용되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 레지스터의 setup time과 hold time의 위반 여부를 분석함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이아웃 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 논리합성을 통해 생성된 게이트 수중netlist를 마스크 제작에 사용될 레이아웃 도면으로 변환하는 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 자동 배치/배선 툴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 칩 제작 공정에 맞게 미리 설계된 표준 셀 라이브러리, RAM, ROM 등의 매크로 셀, I/O 패드 셀과 설계자가 지정한 타이밍 조건을 적용하여 최적화된 레이아웃 도면을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Post-layout 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 레이아웃으로부터 셀과 배선에 의한 지연 특성을 추출하여 타이밍 특성이 고려된 post-layout 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 게이트 수준 타이밍 시뮬레이션, 레이아웃의 기생 효과를 고려한 STA, 각종 설계 규칙검사 등을 통해 설계의 정확성을 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IObnk/btsOVvRK5nu/NY8h8uATwWyVlTQPtV4vXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IObnk/btsOVvRK5nu/NY8h8uATwWyVlTQPtV4vXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IObnk/btsOVvRK5nu/NY8h8uATwWyVlTQPtV4vXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIObnk%2FbtsOVvRK5nu%2FNY8h8uATwWyVlTQPtV4vXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;259&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RTL 수준과 Gate 수준 Verilog&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r2CP6/btsOXObqhsJ/YFxOBkyXDsbkHTHVKMT2QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r2CP6/btsOXObqhsJ/YFxOBkyXDsbkHTHVKMT2QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r2CP6/btsOXObqhsJ/YFxOBkyXDsbkHTHVKMT2QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr2CP6%2FbtsOXObqhsJ%2FYFxOBkyXDsbkHTHVKMT2QK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;333&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HDL 기반 설계의 장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 설계 시간의 단축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 초기 설계과정에서의 설계오류 수정이 용이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 합성에 의한 회로 생성과 설계 변경이 용이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 설계의 질 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 우수하고 광범위한 하드웨어 기술 능력, 상위 수준의 설계 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 다양한 설계기법의 검색에 의한 최적화 도달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 선택적 최적화 기법을 이용한 합성 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 설계기술이나 공정과 무관한 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 특정 ASIC 제조업체 및 구현기술과 무관한 설계 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 동일한 HDL 설계의 다른 라이브러리 이용한 합성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 신속한 하드웨어 원형화(prototyping) 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 낮은 설계 비용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 상위레벨 설계도구의 사용에 따른 설계 생산성 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 설계기간의 단축에 따른 설계비용의 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 설계자산의 재사용에 의한 설계비용의 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 표준 HDL 및 사용자의 확대&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - IEEE 표준인 동시에 미국 정부의 공인 HDL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 전세계적으로 설계 및 설계정보 교환의 수단으로 사용이 확대&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 효율적인 설계관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - HDL 언어의 구조적 설계 기능을 이용한 전체 설계의 기능별 분할 설계 및 설계관리 및 문서화 용이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N3Ht0/btsOVebBJ6r/55KCTUeou1KDJubkgjmbk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N3Ht0/btsOVebBJ6r/55KCTUeou1KDJubkgjmbk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N3Ht0/btsOVebBJ6r/55KCTUeou1KDJubkgjmbk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN3Ht0%2FbtsOVebBJ6r%2F55KCTUeou1KDJubkgjmbk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;375&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMOS (Complementary Metal Oxide Semiconductor)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NMOS (N-Type Metal Oxide Semiconductor) transistors&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PMOS (P-Type Metal Oxide Semiconductor) transistors&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NMOS Transistor&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;103&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csaIyl/btsOWpXJ8On/Q4BKaIYWIHfds4qyWymkgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csaIyl/btsOWpXJ8On/Q4BKaIYWIHfds4qyWymkgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csaIyl/btsOWpXJ8On/Q4BKaIYWIHfds4qyWymkgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsaIyl%2FbtsOWpXJ8On%2FQ4BKaIYWIHfds4qyWymkgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;103&quot; height=&quot;116&quot; data-origin-width=&quot;103&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Logic '1'을 gate에 가하면 'on'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Logic '0'을 gate에 가하면 'off'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PMOS Transistor&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;96&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZrgnL/btsOWkPPZgV/mSg1SmbGrdDoNhG0wmtxBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZrgnL/btsOWkPPZgV/mSg1SmbGrdDoNhG0wmtxBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZrgnL/btsOWkPPZgV/mSg1SmbGrdDoNhG0wmtxBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZrgnL%2FbtsOWkPPZgV%2FmSg1SmbGrdDoNhG0wmtxBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;96&quot; height=&quot;125&quot; data-origin-width=&quot;96&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Logic '1'을 gate에 가하면 'off'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Logic '0'을 gate에 가하면 'on'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMOS 인버터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TawGy/btsOYaZB9J3/1kp2kj59p0ie7TFTjuKk1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TawGy/btsOYaZB9J3/1kp2kj59p0ie7TFTjuKk1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TawGy/btsOYaZB9J3/1kp2kj59p0ie7TFTjuKk1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTawGy%2FbtsOYaZB9J3%2F1kp2kj59p0ie7TFTjuKk1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;238&quot; height=&quot;316&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwKIju/btsOXgeUIw8/3jpEYKMHMwLoJ3jkkN7Ie0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwKIju/btsOXgeUIw8/3jpEYKMHMwLoJ3jkkN7Ie0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwKIju/btsOXgeUIw8/3jpEYKMHMwLoJ3jkkN7Ie0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwKIju%2FbtsOXgeUIw8%2F3jpEYKMHMwLoJ3jkkN7Ie0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;384&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqOnJE/btsOXQ79QA0/VMFz3i9yne0Ycb8o2qLbX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqOnJE/btsOXQ79QA0/VMFz3i9yne0Ycb8o2qLbX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqOnJE/btsOXQ79QA0/VMFz3i9yne0Ycb8o2qLbX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqOnJE%2FbtsOXQ79QA0%2FVMFz3i9yne0Ycb8o2qLbX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;340&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMOS NAND 게이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s0oWV/btsOWHjEuq7/jgUfNX9Vj7c98Yy0xAC1H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s0oWV/btsOWHjEuq7/jgUfNX9Vj7c98Yy0xAC1H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s0oWV/btsOWHjEuq7/jgUfNX9Vj7c98Yy0xAC1H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs0oWV%2FbtsOWHjEuq7%2FjgUfNX9Vj7c98Yy0xAC1H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;355&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMOS NOR 게이트&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNLe7c/btsOWKN6lNO/MW3Nf6Fyxh7FQ1KXKVdrt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNLe7c/btsOWKN6lNO/MW3Nf6Fyxh7FQ1KXKVdrt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNLe7c/btsOWKN6lNO/MW3Nf6Fyxh7FQ1KXKVdrt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNLe7c%2FbtsOWKN6lNO%2FMW3Nf6Fyxh7FQ1KXKVdrt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;254&quot; height=&quot;348&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CK5BQ/btsOWHDTbtH/0hetbBMVcdRw1l7xFiZoeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CK5BQ/btsOWHDTbtH/0hetbBMVcdRw1l7xFiZoeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CK5BQ/btsOWHDTbtH/0hetbBMVcdRw1l7xFiZoeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCK5BQ%2FbtsOWHDTbtH%2F0hetbBMVcdRw1l7xFiZoeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1048&quot; height=&quot;554&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;543&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfidRc/btsOWHYdKKI/QxcNafaDY9FESvd8fjJ9Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfidRc/btsOWHYdKKI/QxcNafaDY9FESvd8fjJ9Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfidRc/btsOWHYdKKI/QxcNafaDY9FESvd8fjJ9Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfidRc%2FbtsOWHYdKKI%2FQxcNafaDY9FESvd8fjJ9Ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1020&quot; height=&quot;543&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;543&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4RZY1/btsOYGRvRmj/JoWFxbpZwPmgro0triAVX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4RZY1/btsOYGRvRmj/JoWFxbpZwPmgro0triAVX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4RZY1/btsOYGRvRmj/JoWFxbpZwPmgro0triAVX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4RZY1%2FbtsOYGRvRmj%2FJoWFxbpZwPmgro0triAVX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1087&quot; height=&quot;554&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gate_test.v (and)&lt;/p&gt;
&lt;pre id=&quot;code_1751255232068&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps // 10.222

module gate_test(
    input wire a,
    input b, // 생략하면 wire 아무런 언급 안하면 1bit
    output out
    );

    assign out = a &amp;amp; b;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDzndR/btsOWokmghk/tOuNvUQXEM3GMVFv9k7TF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDzndR/btsOWokmghk/tOuNvUQXEM3GMVFv9k7TF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDzndR/btsOWokmghk/tOuNvUQXEM3GMVFv9k7TF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDzndR%2FbtsOWokmghk%2FtOuNvUQXEM3GMVFv9k7TF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;971&quot; height=&quot;425&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gate_test.v (or)&lt;/p&gt;
&lt;pre id=&quot;code_1751260831775&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps // 10.222

module gate_test(
    input wire a,
    input b, // 생략하면 wire 아무런 언급 안하면 1bit
    output out
    );

    assign out = a | b;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cirIuN/btsOW7XAAvX/LzTnYuwfFfxkSvIEz8WKwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cirIuN/btsOW7XAAvX/LzTnYuwfFfxkSvIEz8WKwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cirIuN/btsOW7XAAvX/LzTnYuwfFfxkSvIEz8WKwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcirIuN%2FbtsOW7XAAvX%2FLzTnYuwfFfxkSvIEz8WKwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;973&quot; height=&quot;425&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;509&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7yh7/btsOWB5Uzce/sfKRkwSP0O5Q1XufpesgJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7yh7/btsOWB5Uzce/sfKRkwSP0O5Q1XufpesgJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7yh7/btsOWB5Uzce/sfKRkwSP0O5Q1XufpesgJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7yh7%2FbtsOWB5Uzce%2FsfKRkwSP0O5Q1XufpesgJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;509&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;509&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1751261894026&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps // 10.222

module gate_test(
    input wire a,
    input wire b, // 생략하면 wire 아무런 언급 안하면 1bit
    output led0,
    output led1,
    output led2,
    output led3,
    output led4,
    output led5
    );

    assign led0 = a &amp;amp; b;
    assign led1 = a | b;
    assign led2 = ~(a &amp;amp; b);
    assign led3 = ~(a | b);
    assign led4 = a ^ b;
    assign led5 = ~a;

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmFuaT/btsOXR7FZ5F/lIuK96TkSo1O1JRqLYmKa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmFuaT/btsOXR7FZ5F/lIuK96TkSo1O1JRqLYmKa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmFuaT/btsOXR7FZ5F/lIuK96TkSo1O1JRqLYmKa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmFuaT%2FbtsOXR7FZ5F%2FlIuK96TkSo1O1JRqLYmKa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;426&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gate_test.v (배열)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mMWUp/btsOY5cPjr5/putOEcowkcW18bS7qEr9sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mMWUp/btsOY5cPjr5/putOEcowkcW18bS7qEr9sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mMWUp/btsOY5cPjr5/putOEcowkcW18bS7qEr9sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmMWUp%2FbtsOY5cPjr5%2FputOEcowkcW18bS7qEr9sK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;651&quot; height=&quot;500&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1751265287659&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`timescale 1ns / 1ps // 10.222

module gate_test(
    input wire a,
    input wire b, // 생략하면 wire 아무런 언급 안하면 1bit
    output [5:0] led
    // output led0,
    // output led1,
    // output led2,
    // output led3,
    // output led4,
    // output led5
    );

    assign led[0] = a &amp;amp; b; // and
    assign led[1] = a | b; // or
    assign led[2] = ~(a &amp;amp; b); // nand
    assign led[3] = ~(a | b); // nor
    assign led[4] = a ^ b; // xor
    assign led[5] = ~a; // not a

endmodule&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o5rkw/btsOXQA1rpk/NdoCMTRkE0bZOMkk6uFoNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o5rkw/btsOXQA1rpk/NdoCMTRkE0bZOMkk6uFoNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o5rkw/btsOXQA1rpk/NdoCMTRkE0bZOMkk6uFoNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo5rkw%2FbtsOXQA1rpk%2FNdoCMTRkE0bZOMkk6uFoNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;431&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/Verilog HDL</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/528</guid>
      <comments>https://hotari.tistory.com/528#entry528comment</comments>
      <pubDate>Mon, 30 Jun 2025 16:51:11 +0900</pubDate>
    </item>
    <item>
      <title>2일차</title>
      <link>https://hotari.tistory.com/527</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.11&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스의 파일
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일은 리눅스에서 가장 근본적이고 기본적인 추상화-&quot;Every thing is a file&quot;&lt;/li&gt;
&lt;li&gt;상호작용은 상당부분은 파일 읽기와 파일 쓰기로 발생&lt;/li&gt;
&lt;li&gt;파일에 접근하려면 먼저 파일을 열어야한다 - 읽기와 쓰기 목적으로 파일열기가 가능&lt;/li&gt;
&lt;li&gt;열린 파일은 고유한 fd(file descriptor)설명자를 통해 참조되며, 열린 파일과 연관된 메타 데이터와 특정 파일 자체로 다시 매핑&lt;/li&gt;
&lt;li&gt;Linux 커널 내에서 해당 설명자는 file descriptor(fd)로 불리는 정수(C 유형int)에 의해 처리&lt;/li&gt;
&lt;li&gt;fd는 사용자 공간과 공유되며 사용자 프로그램이 파일에 액세스하기 위해 직접 사용함&lt;/li&gt;
&lt;li&gt;Linux 시스템 프로그래밍의 대부분은 파일을 열어서 fd를 할당받고 fd를 이용하여 파일을 조작하고, 닫고 사용하는 것으로 실행된다.&lt;/li&gt;
&lt;li&gt;리눅스의 표준 file descriptors(fd)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Regular 파일
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스에서 일반적으로 파일이라고 하면regular 파일을 말함&lt;/li&gt;
&lt;li&gt;Regular 파일은 바이트 스트림이라 부르는 선형 배열로 구성된 데이터 바이트를 담고 있음-Linux에서는 파일에 대한 추가구성 또는 형식이 지정되지 않음&lt;/li&gt;
&lt;li&gt;바이트는임의의값을가질수있으며, 파일내에서어떤방식으로든구성될수있고, Linux는시스템수준에서 바이트스트림외에는파일에구조를적용하지않음&lt;/li&gt;
&lt;li&gt;파일내의모든바이트를읽을수있고, 쓸수있으며, 파일내의특정바이트에서시작할수있으며, 이시작하는위치를 파일position 또는파일offset 이라고한다-파일을처음열면file offset은0 이며바이트단위로읽거나쓸때offset 값이증가함&lt;/li&gt;
&lt;li&gt;파일중간에바이트를쓰면해당오프셋에있던이전바이트를덮어쓰기때문에파일중간에서부터 파일을확장할수 없으며대부분의파일쓰기는파일끝에서발생&lt;/li&gt;
&lt;li&gt;파일의크기는바이트단위로측정되며 파일의크기를나타내는길이는단순히파일을구성하는선형배열의바이트수를 말함&lt;/li&gt;
&lt;li&gt;동일한프로세스또는다른프로세스에서단일파일을여러번open 할수있고, 열린파일의인스턴스에고유한file descriptor(fd)가 부여됨&lt;/li&gt;
&lt;li&gt;프로세는file descriptor(fd)를 공유할수있고, file descriptor는 하나이상의프로세스에서 사용될수있다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커널에서제약이없기때문에사용자공간에서동기화에대한조정이필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;파일은파일이름으로접근하지만 실제로는파일시스템에서 할당된고유한정수값,inode에의해참조된다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;할당된inode 정수값을inode number, i-number, ino 등으로부름&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스 파일 제어
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스파일 제어와 관련된 system call과 libraryclose / fcloseread / freadstat, lstatlink / unlink / symlinkumaskmkdir, rmdiropendir, readdir, closedir&lt;/li&gt;
&lt;li&gt;rename&lt;/li&gt;
&lt;li&gt;getcwd, chdir&lt;/li&gt;
&lt;li&gt;chmod, chown&lt;/li&gt;
&lt;li&gt;utime&lt;/li&gt;
&lt;li&gt;dup, dup2&lt;/li&gt;
&lt;li&gt;access&lt;/li&gt;
&lt;li&gt;write / fwrite&lt;/li&gt;
&lt;li&gt;open / fopen / creat&lt;/li&gt;
&lt;li&gt;파일 열기(open)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커널은 프로세스 별로 열린 파일을 관리-file table&lt;/li&gt;
&lt;li&gt;열린 파일은 file descriptor(fd)로 색인화됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bt3qXn/btsOSOp3jZX/FjKdI5hBxuJf0v35196mw0/01.write.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01.write.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/2zCnE/btsOT9Uxxjj/yJF16zvlktd7Iz4klhe7Bk/02.read.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02.read.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/PregD/btsOTgUJzEz/HATo6sk8kztBKBiWTyTjb0/02.read_fixed.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02.read_fixed.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cIKTcB/btsOTK8K1z9/M222vQ3XuzLSfZBQnS91Q1/03.fwrite.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03.fwrite.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bFtWcW/btsOSR8JfYx/b3K9BqLMwYvWPpY9c8EywK/04.fread.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04.fread.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/nwxD8/btsOTxVCljO/5ACHgqxFjelLuS79zii7m0/05.access.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05.access.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/lHAhC/btsOUqPhfCy/gLIACiqTGsaJknfnaIHKMK/05.access_fixed.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05.access_fixed.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/OtdCN/btsOSv5jjqf/e2MQoJlGF8oYnbE70959Xk/05.access_fixed_all.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05.access_fixed_all.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/QBQxC/btsOTWOEV1C/kVYyR4Tj2SXmgeJQy0NYz0/06.lstat.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;06.lstat.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/5yUzN/btsOUzrzhxn/6zSXu1VuU7Z3A8O4A62dDK/07.dup2.c?attach=1&amp;amp;knm=tfile.c&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;07.dup2.c&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/527</guid>
      <comments>https://hotari.tistory.com/527#entry527comment</comments>
      <pubDate>Fri, 27 Jun 2025 09:18:27 +0900</pubDate>
    </item>
    <item>
      <title>Mini Proejct1 - Socket Driver Arcade</title>
      <link>https://hotari.tistory.com/526</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Socket Driver Arcade Project&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bstzxp/btsOUgy2BnV/C9k20ILF0jFQekQzoBnzCk/SOCKET_DRIVER_ARCADE.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;SOCKET_DRIVER_ARCADE.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.73MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#&amp;nbsp;Socket_Driver_Arcade&lt;br /&gt;&lt;br /&gt;실행&amp;nbsp;방법&lt;br /&gt;&lt;br /&gt;Ubuntu&amp;nbsp;환경&lt;br /&gt;1.&amp;nbsp;vim&amp;nbsp;lcd1602.c&lt;br /&gt;2.&amp;nbsp;vim&amp;nbsp;Makefile&lt;br /&gt;3.&amp;nbsp;make&amp;nbsp;-j12&amp;nbsp;ARCH=arm64&amp;nbsp;CROSS_COMPILE=aarch64-linux-gnu-&lt;br /&gt;4.&amp;nbsp;scp&amp;nbsp;lcd1602.ko&amp;nbsp;pi@ip주소:/home/pi&lt;br /&gt;&lt;br /&gt;Raspi&amp;nbsp;환경&lt;br /&gt;1.&amp;nbsp;sudo&amp;nbsp;insmod&amp;nbsp;lcd1602.ko&lt;br /&gt;2.&amp;nbsp;sudo&amp;nbsp;chmod&amp;nbsp;666&amp;nbsp;/dev/lcd1602&lt;br /&gt;3.&amp;nbsp;dmesg&amp;nbsp;|&amp;nbsp;tail로&amp;nbsp;lcd1602&amp;nbsp;register&amp;nbsp;확인&lt;br /&gt;4.&amp;nbsp;sudo&amp;nbsp;mknod&amp;nbsp;/dev/lcd1602&amp;nbsp;c&amp;nbsp;$MAJOR&amp;nbsp;$MINOR&amp;nbsp;(dmesg&amp;nbsp;|&amp;nbsp;tail로&amp;nbsp;확인)&lt;br /&gt;5.&amp;nbsp;vim&amp;nbsp;server_final.c&lt;br /&gt;6.&amp;nbsp;gcc&amp;nbsp;server_final.c&amp;nbsp;-o&amp;nbsp;server_final&lt;br /&gt;7.&amp;nbsp;vim&amp;nbsp;client_final.c&lt;br /&gt;8.&amp;nbsp;gcc&amp;nbsp;client_final.c&amp;nbsp;-o&amp;nbsp;client_final&lt;br /&gt;9.&amp;nbsp;./server_final&lt;br /&gt;10.&amp;nbsp;./client_final&amp;nbsp;ip주소&amp;nbsp;-&amp;nbsp;플레이어&amp;nbsp;2명&amp;nbsp;접속&lt;br /&gt;11.&amp;nbsp;게임&amp;nbsp;실행&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;멀티플레이어&amp;nbsp;터미널&amp;nbsp;미니&amp;nbsp;게임,&amp;nbsp;LCD1602&amp;nbsp;&amp;amp;&amp;nbsp;LED&amp;nbsp;하드웨어&amp;nbsp;피드백&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;프로젝트는&amp;nbsp;C로&amp;nbsp;구현한&amp;nbsp;간단한&amp;nbsp;멀티플레이어&amp;nbsp;미니게임&amp;nbsp;서버&amp;middot;클라이언트&amp;nbsp;프로그램과,&amp;nbsp;Raspberry&amp;nbsp;Pi의&amp;nbsp;하드웨어(LED&amp;nbsp;및&amp;nbsp;I2C&amp;nbsp;LCD1602&amp;nbsp;디스플레이)를&amp;nbsp;이용해&amp;nbsp;플레이어&amp;nbsp;점수&amp;nbsp;및&amp;nbsp;라운드&amp;nbsp;승자를&amp;nbsp;시각적으로&amp;nbsp;출력하는&amp;nbsp;예제입니다.&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;목차&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;[주요&amp;nbsp;기능](#주요-기능)&lt;br /&gt;*&amp;nbsp;[하드웨어&amp;nbsp;구성](#하드웨어-구성)&lt;br /&gt;*&amp;nbsp;[소프트웨어&amp;nbsp;요구사항](#소프트웨어-요구사항)&lt;br /&gt;*&amp;nbsp;[프로젝트&amp;nbsp;구조](#프로젝트-구조)&lt;br /&gt;*&amp;nbsp;[빌드&amp;nbsp;방법](#빌드-방법)&lt;br /&gt;*&amp;nbsp;[사용법](#사용법)&lt;br /&gt;*&amp;nbsp;[코드&amp;nbsp;개요](#코드-개요)&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;주요&amp;nbsp;기능&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;**3가지&amp;nbsp;미니게임**:&amp;nbsp;가위바위보,&amp;nbsp;연산&amp;nbsp;대결,&amp;nbsp;반응&amp;nbsp;속도&amp;nbsp;게임&lt;br /&gt;*&amp;nbsp;**두&amp;nbsp;명&amp;nbsp;동시&amp;nbsp;플레이**:&amp;nbsp;TCP&amp;nbsp;클라이언트&amp;nbsp;2명이&amp;nbsp;각&amp;nbsp;라운드에&amp;nbsp;참여&lt;br /&gt;*&amp;nbsp;**자동&amp;nbsp;점수&amp;nbsp;집계**:&amp;nbsp;3라운드&amp;nbsp;종료&amp;nbsp;후&amp;nbsp;승/패&amp;nbsp;결과&amp;nbsp;요약&lt;br /&gt;*&amp;nbsp;**하드웨어&amp;nbsp;피드백**:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;**LED**:&amp;nbsp;각&amp;nbsp;라운드별&amp;nbsp;승리&amp;nbsp;시&amp;nbsp;해당&amp;nbsp;라운드&amp;nbsp;LED(총&amp;nbsp;3개)&amp;nbsp;점등&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;**LCD1602**:&amp;nbsp;최종&amp;nbsp;점수&amp;nbsp;요약을&amp;nbsp;I2C&amp;nbsp;LCD1602에&amp;nbsp;표시&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;하드웨어&amp;nbsp;구성&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;**LED&amp;nbsp;(GPIO&amp;nbsp;제어)**&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;라운드1&amp;rarr;GPIO17&amp;nbsp;(LED0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;라운드2&amp;rarr;GPIO27&amp;nbsp;(LED1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;라운드3&amp;rarr;GPIO22&amp;nbsp;(LED2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;각&amp;nbsp;LED는&amp;nbsp;330&amp;Omega;&amp;nbsp;저항과&amp;nbsp;함께&amp;nbsp;Raspberry&amp;nbsp;Pi&amp;nbsp;GND에&amp;nbsp;연결&lt;br /&gt;*&amp;nbsp;**I2C&amp;nbsp;LCD1602&amp;nbsp;디스플레이**&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;SDA&amp;nbsp;&amp;rarr;&amp;nbsp;GPIO2&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;SCL&amp;nbsp;&amp;rarr;&amp;nbsp;GPIO3&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;모듈&amp;nbsp;주소:&amp;nbsp;0x27&lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;4.7k&amp;Omega;&amp;nbsp;풀업&amp;nbsp;저항&amp;nbsp;(보드&amp;nbsp;내장&amp;nbsp;또는&amp;nbsp;외부)&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;소프트웨어&amp;nbsp;요구사항&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;Raspberry&amp;nbsp;Pi&amp;nbsp;OS&amp;nbsp;(Raspbian&amp;nbsp;등)&lt;br /&gt;*&amp;nbsp;`gcc`,&amp;nbsp;`make`,&amp;nbsp;`pthread`&amp;nbsp;라이브러리&lt;br /&gt;*&amp;nbsp;`i2c-tools`&amp;nbsp;(I2C&amp;nbsp;버스&amp;nbsp;확인&amp;nbsp;및&amp;nbsp;디버깅)&lt;br /&gt;*&amp;nbsp;`raspi-gpio`&amp;nbsp;유틸리티&amp;nbsp;(GPIO&amp;nbsp;제어)&lt;br /&gt;*&amp;nbsp;I2C&amp;nbsp;활성화:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;```bash&lt;br /&gt;&amp;nbsp;&amp;nbsp;sudo&amp;nbsp;raspi-config&amp;nbsp;nonint&amp;nbsp;do_i2c&amp;nbsp;0&lt;br /&gt;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;프로젝트&amp;nbsp;구조&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;project/&lt;br /&gt;├──&amp;nbsp;server_final.c&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;게임&amp;nbsp;서버&amp;nbsp;및&amp;nbsp;LCD/LED&amp;nbsp;제어&amp;nbsp;(라운드별&amp;nbsp;LED&amp;nbsp;+&amp;nbsp;LCD)&lt;br /&gt;├──&amp;nbsp;client_final.c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;게임&amp;nbsp;클라이언트&amp;nbsp;(터미널&amp;nbsp;인터페이스)&lt;br /&gt;├──&amp;nbsp;lcd1602.c&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;I2C&amp;nbsp;LCD1602&amp;nbsp;커널&amp;nbsp;모듈&lt;br /&gt;└──&amp;nbsp;Makefile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;빌드&amp;nbsp;스크립트&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;빌드&amp;nbsp;방법&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;프로젝트&amp;nbsp;디렉터리를&amp;nbsp;Raspberry&amp;nbsp;Pi로&amp;nbsp;복사&lt;br /&gt;2.&amp;nbsp;의존성&amp;nbsp;설치:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;```bash&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sudo&amp;nbsp;apt&amp;nbsp;update&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sudo&amp;nbsp;apt&amp;nbsp;install&amp;nbsp;build-essential&amp;nbsp;i2c-tools&amp;nbsp;raspi-gpio&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;3.&amp;nbsp;빌드:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;```bash&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;make&amp;nbsp;-j12&amp;nbsp;ARCH=arm64&amp;nbsp;CROSS_COMPILE=aarch64-linux-gnu-&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;rarr;&amp;nbsp;`server_final`,&amp;nbsp;`client_final`,&amp;nbsp;`lcd1602.ko`&amp;nbsp;생성&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;사용법&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;1.&amp;nbsp;LCD&amp;nbsp;커널&amp;nbsp;모듈&amp;nbsp;로드&lt;br /&gt;&lt;br /&gt;```bash&lt;br /&gt;sudo&amp;nbsp;insmod&amp;nbsp;lcd1602.ko&lt;br /&gt;sudo&amp;nbsp;chmod&amp;nbsp;666&amp;nbsp;/dev/lcd1602&lt;br /&gt;sudo&amp;nbsp;mknod&amp;nbsp;/dev/lcd1602&amp;nbsp;c&amp;nbsp;$MAJOR&amp;nbsp;$MINOR&amp;nbsp;(dmesg&amp;nbsp;|&amp;nbsp;tail에서&amp;nbsp;번호&amp;nbsp;확인)&lt;br /&gt;ls&amp;nbsp;-l&amp;nbsp;/dev/lcd1602&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;2.&amp;nbsp;서버&amp;nbsp;실행&lt;br /&gt;&lt;br /&gt;```bash&lt;br /&gt;sudo&amp;nbsp;./server_final&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;포트&amp;nbsp;10000에서&amp;nbsp;두&amp;nbsp;명의&amp;nbsp;클라이언트&amp;nbsp;연결을&amp;nbsp;대기&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;3.&amp;nbsp;클라이언트&amp;nbsp;접속&lt;br /&gt;&lt;br /&gt;두&amp;nbsp;개의&amp;nbsp;터미널에서:&lt;br /&gt;&lt;br /&gt;```bash&lt;br /&gt;./client_final&amp;nbsp;&amp;lt;서버_IP&amp;gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;4.&amp;nbsp;하드웨어&amp;nbsp;피드백&amp;nbsp;확인&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;**라운드별&amp;nbsp;LED**:&amp;nbsp;각&amp;nbsp;라운드&amp;nbsp;종료&amp;nbsp;시&amp;nbsp;플레이어1이&amp;nbsp;이긴&amp;nbsp;라운드&amp;nbsp;LED만&amp;nbsp;점등&lt;br /&gt;*&amp;nbsp;**LCD1602**:&amp;nbsp;3라운드&amp;nbsp;종료&amp;nbsp;후&amp;nbsp;다음&amp;nbsp;내용&amp;nbsp;표시:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&amp;nbsp;&amp;nbsp;P1:&amp;nbsp;X&amp;nbsp;win&amp;nbsp;Y&amp;nbsp;lose&lt;br /&gt;&amp;nbsp;&amp;nbsp;P2:&amp;nbsp;A&amp;nbsp;win&amp;nbsp;B&amp;nbsp;lose&lt;br /&gt;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;코드&amp;nbsp;개요&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;`server_final.c`&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;**네트워크**:&amp;nbsp;TCP&amp;nbsp;소켓&amp;nbsp;생성,&amp;nbsp;포트&amp;nbsp;10000&amp;nbsp;바인딩,&amp;nbsp;최대&amp;nbsp;2명&amp;nbsp;접속&lt;br /&gt;2.&amp;nbsp;**미니게임&amp;nbsp;로직**&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;`play_rps()`,&amp;nbsp;`play_math()`,&amp;nbsp;`play_react()`&amp;nbsp;함수&lt;br /&gt;3.&amp;nbsp;**라운드별&amp;nbsp;LED&amp;nbsp;제어**&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;`round_winners[3]`에&amp;nbsp;각&amp;nbsp;라운드&amp;nbsp;승자(0&amp;nbsp;또는&amp;nbsp;1)&amp;nbsp;저장&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;`led_per_round()`&amp;nbsp;함수에서&amp;nbsp;승자&amp;nbsp;배열&amp;nbsp;참조,&amp;nbsp;`raspi-gpio`로&amp;nbsp;GPIO17/27/22&amp;nbsp;제어&lt;br /&gt;4.&amp;nbsp;**LCD&amp;nbsp;제어**&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;`/dev/lcd1602`에&amp;nbsp;write하여&amp;nbsp;I2C&amp;nbsp;LCD1602&amp;nbsp;출력&lt;br /&gt;5.&amp;nbsp;**결과&amp;nbsp;전송&amp;nbsp;및&amp;nbsp;정리**&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;`client_final.c`&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;서버&amp;nbsp;연결&amp;nbsp;및&amp;nbsp;게임&amp;nbsp;입력/출력&amp;nbsp;처리&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;`lcd1602.c`&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;I2C&amp;nbsp;LCD1602&amp;nbsp;커널&amp;nbsp;모듈&amp;nbsp;(dynamic&amp;nbsp;char&amp;nbsp;device)&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;##&amp;nbsp;데모&amp;nbsp;동영상&lt;br /&gt;&lt;br /&gt;아래&amp;nbsp;링크에서&amp;nbsp;프로젝트&amp;nbsp;실행&amp;nbsp;모습을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있습니다:&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;[&lt;a href=&quot;https://youtu.be/a2IlBgpWruA](https://youtu.be/a2IlBgpWruA)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/a2IlBgpWruA](https://youtu.be/a2IlBgpWruA)&lt;/a&gt;&lt;br /&gt;*&amp;nbsp;[&lt;a href=&quot;https://youtube.com/shorts/zeM5-n1U8Fc](https://youtube.com/shorts/zeM5-n1U8Fc)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/zeM5-n1U8Fc](https://youtube.com/shorts/zeM5-n1U8Fc)&lt;/a&gt;&lt;br /&gt;*&amp;nbsp;[&lt;a href=&quot;https://youtube.com/shorts/pw4d3U6k4-s](https://youtube.com/shorts/pw4d3U6k4-s)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/pw4d3U6k4-s](https://youtube.com/shorts/pw4d3U6k4-s)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;---&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750983027315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;핵심코드
server.c
  1. TCP 서버 초기화 및 클라이언트 연결 대기
int sock = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &amp;amp;opt, sizeof(opt));

struct sockaddr_in addr = { AF_INET, htons(PORT), INADDR_ANY };
bind(sock, (struct sockaddr*)&amp;amp;addr, sizeof(addr));
listen(sock, MAX_CLIENTS);

while (cnt &amp;lt; MAX_CLIENTS) {
    int cfd = accept(sock, NULL, NULL);
    client_info_t *ci = malloc(sizeof(*ci));
    ci-&amp;gt;sockfd = cfd; ci-&amp;gt;player_id = cnt;
    clients[cnt++] = ci;
    pthread_create(&amp;amp;tid, NULL, client_thread, ci);
    pthread_detach(tid);
}
​
 ️ 설명:
TCP 소켓 생성 후 바인딩 &amp;rarr; 최대 2명 클라이언트 접속 대기
접속마다 개별 스레드 할당
pthread로 병렬 처리
  2. 클라이언트 스레드 진입 처리: client_thread()
void *client_thread(void *arg) {
    client_info_t *ci = arg;
    char buf[BUF_SIZE];
    snprintf(buf, sizeof(buf), &quot;[서버] Player %d 입장\n&quot;, ci-&amp;gt;player_id+1);
    send(ci-&amp;gt;sockfd, buf, strlen(buf), 0);

    while (1) {
        pthread_mutex_lock(&amp;amp;game.lock);
        if (clients[0] &amp;amp;&amp;amp; clients[1]) {
            pthread_mutex_unlock(&amp;amp;game.lock);
            break;
        }
        pthread_mutex_unlock(&amp;amp;game.lock);
        usleep(100000);
    }
    return NULL;
}
​
구성 요소
설명
client_info_t
각 클라이언트의 소켓 FD와 플레이어 ID 정보 저장
send()
접속 확인 메시지 전송 (Player 1 입장, Player 2 입장)
pthread_mutex
두 클라이언트 모두 연결될 때까지 락을 걸고 조건 확인
usleep(100000)
바쁜 대기를 피하기 위한 0.1초 sleep, CPU 낭비 최소화
비동기 입장 처리
&amp;rarr; 각 클라이언트 입장 후 별도 스레드에서 대기
Race condition 방지
&amp;rarr; pthread_mutex_lock()을 이용해 clients[] 접근 시 동기화
게임 진행 제어점
&amp;rarr; 두 명 모두 입장해야 게임 진행 가능 (main thread에서 round 시작)
클라이언트 스레드는 입장 알림 및 진입 동기화 역할만 수행
이후 게임 로직은 main thread가 직접 관리
멀티플레이 환경에서 정확한 입장 타이밍 제어를 위한 핵심 함수
  3. 게임 제어 및 통신 루프 (핵심 로직)
int (*games[3])(client_info_t*, client_info_t*) = { play_rps, play_math, play_react };
while (game.current_round &amp;lt; 3) {
    int r = game.current_round;
    int w = games[r](clients[0], clients[1]);
    round_winners[r] = w;
    game.scores[w]++;
    game.current_round++;
    for (int i = 0; i &amp;lt; MAX_CLIENTS; i++) {
        send(clients[i]-&amp;gt;sockfd,
             i == w ? &quot;WIN\n&quot; : &quot;LOSE\n&quot;,
             i == w ? 4 : 5, 0);
    }
}
​
 ️ 설명:
가위바위보, 연산, 반응 속도 게임을 차례로 진행
각 라운드마다 승자를 판단하고 점수 반영
클라이언트에게 WIN/LOSE 결과 전송
  4. 디바이스 연동: LCD + LED 제어
// LCD 출력용 메시지 생성
snprintf(line1, sizeof(line1), &quot;P1:%d win %d lose&quot;, p1, 3-p1);
snprintf(line2, sizeof(line2), &quot;P2:%d win %d lose&quot;, p2, 3-p2);
memcpy(out, line1, 16);
memcpy(out + 16, line2, 16);
lcd_write(out);  // /dev/lcd1602에 결과 출력

// LED 피드백
for (int i = 0; i &amp;lt; 3; i++) {
    snprintf(cmd, sizeof(cmd), &quot;raspi-gpio set %d op %s&quot;,
             led_pins[i], round_winners[i] == 0 ? &quot;dh&quot; : &quot;dl&quot;);
    system(cmd);
}

​
 ️ 설명:
/dev/lcd1602를 통해 LCD에 최종 점수 출력
각 라운드 결과를 GPIO LED로 표시 (승자에 따라 High/Low 제어)
raspi-gpio 명령어로 핀 출력 설정
client.c
   1. 서버 연결 초기화
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv = {AF_INET, htons(PORT)};
inet_pton(AF_INET, argv[1], &amp;amp;serv.sin_addr);
if(connect(sockfd, (struct sockaddr*)&amp;amp;serv, sizeof(serv)) &amp;lt; 0) {
    perror(&quot;connect&quot;); exit(1);
}
​
 ️ 설명:
TCP 소켓 생성 (SOCK_STREAM)
서버 주소 설정 및 connect()로 연결
IP는 사용자 인자(argv[1])로 입력
  2. 게임 루프 구조 및 메시지 처리
while(fgets(buf, BUF_SIZE, fp)) {
    if(strncmp(buf, &quot;WIN\n&quot;, 4)==0) { printf(&quot;[결과] 승리!\n&quot;); continue; }
    if(strncmp(buf, &quot;LOSE\n&quot;, 5)==0) { printf(&quot;[결과] 패배.\n&quot;); continue; }
    if(strncmp(buf, &quot;TIE\n&quot;, 4)==0) { printf(&quot;[결과] 무승부!\n&quot;); continue; }
    ...
​
 ️ 설명:
서버에서 오는 문자열 메시지를 기준으로 분기 처리
결과 메시지 (WIN, LOSE, TIE)는 단순 출력
  3. 미니게임 입력 처리 (예: 가위바위보)
if(strncmp(buf, &quot;RPS&quot;, 3)==0) {
    printf(&quot;[게임: 가위바위보] rock/paper/scissors 입력: &quot;);
    char in[BUF_SIZE];
    fgets(in, BUF_SIZE, stdin);
    in[strcspn(in,&quot;\n&quot;)] = '\0';
    fprintf(fp, &quot;%s\n&quot;, in);
    fflush(fp);
}
​
 ️ 설명:
서버의 지시에 따라 입력 요청
사용자 입력을 줄바꿈 제거 후 서버로 전송
구조는 MATH, REACT도 유사
i2c_lcd.c
  1. 프로젝트 내 LCD 드라이버의 역할
  목적: 게임 서버 결과를 하드웨어 LCD에 출력

  위치: server 에서 write(&quot;/dev/lcd1602&quot;) 호출
&amp;rarr; LCD 디바이스 드라이버가 이를 처리하여 실제 I2C 전송 수행

✅ 주요 기술요소
- 문자 디바이스 드라이버
- I2C client 장치 생성
- 데이터시트 기반 LCD 제어 (4bit 모드)
​
  2. 드라이버 구조 개요
[사용자 공간] &amp;rarr; echo &quot;P1:1 P2:2&quot; &amp;gt; /dev/lcd1602
                   &amp;darr; write() 호출

[커널 공간]   &amp;rarr; lcd_write() 함수 진입
                   &amp;darr;
                I2C 통신 (i2c_master_send)
                   &amp;darr;
[실제 하드웨어] LCD1602 
​
  구조 설명:
문자 디바이스 등록
유저 write() &amp;rarr; 문자 &amp;rarr; 커맨드 변환 &amp;rarr; LCD로 전송
  3. 문자 디바이스 등록 과정
alloc_chrdev_region(&amp;amp;lcd_dev, 0, 1, &quot;lcd1602&quot;);
cdev_init(&amp;amp;lcd_cdev, &amp;amp;lcd_fops);
cdev_add(&amp;amp;lcd_cdev, lcd_dev, 1);
​
  설명:
alloc_chrdev_region()으로 major/minor 동적 할당
cdev_add()로 write 시스템콜 연결
결과: /dev/lcd1602 자동 생성됨
  4. I2C 클라이언트 장치 등록
struct i2c_board_info info = {
    .type = &quot;lcd1602&quot;,
    .addr = 0x27,
};
adap = i2c_get_adapter(1);
lcd_client = i2c_new_client_device(adap, &amp;amp;info);
​
  설명:
Raspberry Pi의 I2C-1 버스에서 주소 0x27의 장치 등록
이후 i2c_master_send()로 해당 장치에 데이터 전송 가능
lcd_client가 하드웨어 포인터 역할(I2C 디바이스를 나타내는 커널 구조체 포인터)
  5. LCD 초기화 시퀀스 (HD44780, 4bit)
lcd_cmd(0x33);  // 초기화
lcd_cmd(0x32);  // 4bit 모드 설정
lcd_cmd(0x28);  // 2줄, 5x8도트
lcd_cmd(0x0C);  // 화면 ON, 커서 OFF
lcd_cmd(0x06);  // 자동 커서 이동
lcd_cmd(0x01);  // 화면 clear
​
  설명:
HD44780의 초기화 순서를 정확히 따름
LCD1602는 실제로 4bit만 사용되므로 두 번에 나눠 전송
  6. 명령/데이터 전송 구조
void lcd_send(u8 val, u8 rs) {
    write4(val, 0);         // 상위 4비트
    write4(val &amp;lt;&amp;lt; 4, rs);   // 하위 4비트
}

void write4(u8 nibble, u8 ctrl) {
    u8 data = (nibble &amp;amp; 0xF0) | ctrl | LCD_BACKLIGHT;
    i2c_master_send(lcd_client, &amp;amp;data, 1);
    pulse_enable(data);
}
​
  설명:
한 글자를 4bit 단위로 나눠 두 번 전송
RS=0: 커맨드, RS=1: 데이터
LCD Enable 펄스는 latch 역할
  7. write() 시스템콜 구현
char kbuf[33];
copy_from_user(kbuf, buf, len);  // 사용자 버퍼 복사

lcd_cmd(0x01); // 화면 clear
for (i = 0; i &amp;lt; len &amp;amp;&amp;amp; i &amp;lt; 16; i++)
    lcd_data(kbuf[i]);
if (len &amp;gt; 16) {
    lcd_cmd(0xC0); // 둘째 줄로 이동
    for (i = 16; i &amp;lt; len &amp;amp;&amp;amp; i &amp;lt; 32; i++)
        lcd_data(kbuf[i]);
}
​
  설명:
한 줄 16글자 기준
2줄(32자)까지 출력 가능
write() &amp;rarr; 커널 복사 &amp;rarr; i2c 전송
  8. insmod &amp;rarr; 동작 예시 흐름
# 드라이버 삽입
$ sudo insmod lcd1602.ko

# 장치 생성 확인
$ ls /dev/lcd1602

# dmesg 로그 확인
lcd1602: char device registered (major=245, minor=0)
lcd1602: LCD initialized
​
  설명:
실제 리눅스 환경에서 사용자가 어떻게 접근하는지 명확히 제시
  9. 커널 모듈 exit 및 정리
void __exit lcd_exit_module(void) {
    i2c_unregister_device(lcd_client);
    cdev_del(&amp;amp;lcd_cdev);
    unregister_chrdev_region(lcd_dev, 1);
}
​
  설명:
rmmod lcd1602 시 안전하게 I2C 장치 제거
문자 디바이스 및 major 번호 반납
  10. 요약: LCD 드라이버 설계의 핵심
✅ 문자 디바이스와 I2C 통신을 커널 모듈에서 직접 구현
✅ 사용자 공간 &amp;harr; 커널 &amp;harr; 하드웨어 구조 완전 이해
✅ 게임 서버 결과 &amp;rarr; 실시간 LCD 출력으로 시각화
✅ 시스템 콜 / 하드웨어 통신 / 커맨드 제어 모두 아우른 종합 설계&lt;/code&gt;&lt;/pre&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스 mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/526</guid>
      <comments>https://hotari.tistory.com/526#entry526comment</comments>
      <pubDate>Fri, 27 Jun 2025 09:07:23 +0900</pubDate>
    </item>
    <item>
      <title>10일차</title>
      <link>https://hotari.tistory.com/525</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.24&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BMP180&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i2c라이브러리를 이용해서 기압 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bmp180_i2c.c&lt;/p&gt;
&lt;pre id=&quot;code_1750751800662&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;linux/i2c-dev.h&amp;gt;
#include &amp;lt;math.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;

// BMP180 I2C 주소 및 레지스터
#define BMP180_ADDRESS           0x77
#define BMP180_REG_CAL_AC1       0xAA
#define BMP180_REG_CONTROL       0xF4
#define BMP180_REG_RESULT        0xF6
#define BMP180_CMD_READ_TEMP     0x2E
#define BMP180_CMD_READ_PRESSURE 0x34

// 보정 계수 전역 저장
static short ac1, ac2, ac3, b1, b2, mb, mc, md;
static unsigned short ac4, ac5, ac6;

static int i2c_fd;

// 함수 프로토타입
static void  read_calibration_data(void);
static unsigned int read_ut(void);
static unsigned int read_up(int oss);

// 보정 데이터 읽기
static void read_calibration_data(void) {
    unsigned char buf[22];
    if (read(i2c_fd, buf, 22) != 22) {
        perror(&quot;Failed to read calibration data&quot;);
        exit(1);
    }
    ac1 = (buf[0] &amp;lt;&amp;lt; 8) | buf[1];
    ac2 = (buf[2] &amp;lt;&amp;lt; 8) | buf[3];
    ac3 = (buf[4] &amp;lt;&amp;lt; 8) | buf[5];
    ac4 = (buf[6] &amp;lt;&amp;lt; 8) | buf[7];
    ac5 = (buf[8] &amp;lt;&amp;lt; 8) | buf[9];
    ac6 = (buf[10] &amp;lt;&amp;lt; 8) | buf[11];
    b1  = (buf[12] &amp;lt;&amp;lt; 8) | buf[13];
    b2  = (buf[14] &amp;lt;&amp;lt; 8) | buf[15];
    mb  = (buf[16] &amp;lt;&amp;lt; 8) | buf[17];
    mc  = (buf[18] &amp;lt;&amp;lt; 8) | buf[19];
    md  = (buf[20] &amp;lt;&amp;lt; 8) | buf[21];
}

// 원시 온도 읽기
static unsigned int read_ut(void) {
    unsigned char cmd[2] = { BMP180_REG_CONTROL, BMP180_CMD_READ_TEMP };
    if (write(i2c_fd, cmd, 2) != 2) {
        perror(&quot;Failed to write temp cmd&quot;);
        exit(1);
    }
    usleep(5000);

    unsigned char reg = BMP180_REG_RESULT;
    if (write(i2c_fd, &amp;amp;reg, 1) != 1) {
        perror(&quot;Failed to set temp read ptr&quot;);
        exit(1);
    }

    unsigned char buf[2];
    if (read(i2c_fd, buf, 2) != 2) {
        perror(&quot;Failed to read uncomp temp&quot;);
        exit(1);
    }
    return (buf[0] &amp;lt;&amp;lt; 8) | buf[1];
}

// 원시 압력 읽기
static unsigned int read_up(int oss) {
    unsigned char cmd[2] = { BMP180_REG_CONTROL,
        (unsigned char)(BMP180_CMD_READ_PRESSURE + (oss &amp;lt;&amp;lt; 6)) };
    if (write(i2c_fd, cmd, 2) != 2) {
        perror(&quot;Failed to write press cmd&quot;);
        exit(1);
    }
    // OSS에 따른 대기
    switch (oss) {
        case 0: usleep(5000);  break;
        case 1: usleep(8000);  break;
        case 2: usleep(14000); break;
        case 3: usleep(26000); break;
    }

    unsigned char reg = BMP180_REG_RESULT;
    if (write(i2c_fd, &amp;amp;reg, 1) != 1) {
        perror(&quot;Failed to set press read ptr&quot;);
        exit(1);
    }

    unsigned char buf[3];
    if (read(i2c_fd, buf, 3) != 3) {
        perror(&quot;Failed to read uncomp press&quot;);
        exit(1);
    }
    return (((buf[0] &amp;lt;&amp;lt; 16) | (buf[1] &amp;lt;&amp;lt; 8) | buf[2]) &amp;gt;&amp;gt; (8 - oss));
}

int main(void) {
    const char *i2c_dev = &quot;/dev/i2c-1&quot;;

    // I2C 버스 오픈
    if ((i2c_fd = open(i2c_dev, O_RDWR)) &amp;lt; 0) {
        perror(&quot;Open i2c bus&quot;);
        return 1;
    }
    if (ioctl(i2c_fd, I2C_SLAVE, BMP180_ADDRESS) &amp;lt; 0) {
        perror(&quot;ioctl I2C_SLAVE&quot;);
        return 1;
    }

    // 보정 데이터 읽기 위치 설정
    unsigned char start = BMP180_REG_CAL_AC1;
    if (write(i2c_fd, &amp;amp;start, 1) != 1) {
        perror(&quot;Set cal data ptr&quot;);
        return 1;
    }
    read_calibration_data();

    printf(&quot;BMP180 실시간 측정 시작 (Ctrl+C 또는 Ctrl+Z 로 종료)\n\n&quot;);

    while (1) {
        // 원시값 읽기
        unsigned int ut = read_ut();
        unsigned int up = read_up(3);  // 최고 해상도 OSS=3

        // 온도 계산
        long x1 = ((long)ut - ac6) * ac5 &amp;gt;&amp;gt; 15;
        long x2 = ((long)mc &amp;lt;&amp;lt; 11) / (x1 + md);
        long b5 = x1 + x2;
        double temperature = ((b5 + 8) &amp;gt;&amp;gt; 4) / 10.0;  // &amp;deg;C

        // 압력 계산
        long b6 = b5 - 4000;
        x1 = (b2 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 11;
        x2 = (ac2 * b6) &amp;gt;&amp;gt; 11;
        long x3 = x1 + x2;
        long b3 = ((((long)ac1 * 4 + x3) &amp;lt;&amp;lt; 3) + 2) &amp;gt;&amp;gt; 2;
        x1 = (ac3 * b6) &amp;gt;&amp;gt; 13;
        x2 = (b1 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 16;
        x3 = ((x1 + x2) + 2) &amp;gt;&amp;gt; 2;
        unsigned long b4 = (ac4 * (unsigned long)(x3 + 32768)) &amp;gt;&amp;gt; 15;
        unsigned long b7 = ((unsigned long)up - b3) * (50000 &amp;gt;&amp;gt; 3);
        long p;
        if (b7 &amp;lt; 0x80000000)
            p = (b7 * 2) / b4;
        else
            p = (b7 / b4) * 2;
        x1 = (p &amp;gt;&amp;gt; 8) * (p &amp;gt;&amp;gt; 8);
        x1 = (x1 * 3038) &amp;gt;&amp;gt; 16;
        x2 = (-7357 * p) &amp;gt;&amp;gt; 16;
        p = p + ((x1 + x2 + 3791) &amp;gt;&amp;gt; 4);

        double pressure_hpa = p / 100.0;

        printf(&quot;온도: %.2f &amp;deg;C    압력: %.2f hPa\n&quot;,
               temperature, pressure_hpa);

        sleep(1);
    }

    close(i2c_fd);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스 드라이버 개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bmp180.c&lt;/p&gt;
&lt;pre id=&quot;code_1750751702331&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-2.0
#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/kernel.h&amp;gt;
#include &amp;lt;linux/i2c.h&amp;gt;
#include &amp;lt;linux/delay.h&amp;gt;
#include &amp;lt;linux/mutex.h&amp;gt;
#include &amp;lt;linux/sysfs.h&amp;gt;
#include &amp;lt;linux/of.h&amp;gt;
#include &amp;lt;linux/of_device.h&amp;gt;

#define BMP180_REG_CALIB   0xAA
#define BMP180_REG_CTRL    0xF4
#define BMP180_REG_DATA    0xF6
#define BMP180_CMD_TEMP    0x2E
#define BMP180_CMD_PRESS   0x34

struct bmp180_data {
    struct i2c_client *client;
    struct mutex      lock;
    /* Calibration coefficients */
    s16  ac1, ac2, ac3, b1, b2, mb, mc, md;
    u16  ac4, ac5, ac6;
    int  oss;
};

static int bmp180_read_calib(struct bmp180_data *d)
{
    u8 buf[22];
    int ret;

    ret = i2c_smbus_read_i2c_block_data(d-&amp;gt;client,
                                        BMP180_REG_CALIB,
                                        sizeof(buf), buf);
    if (ret &amp;lt; 0)
        return ret;

    d-&amp;gt;ac1 = (buf[0] &amp;lt;&amp;lt; 8) | buf[1];
    d-&amp;gt;ac2 = (buf[2] &amp;lt;&amp;lt; 8) | buf[3];
    d-&amp;gt;ac3 = (buf[4] &amp;lt;&amp;lt; 8) | buf[5];
    d-&amp;gt;ac4 = (buf[6] &amp;lt;&amp;lt; 8) | buf[7];
    d-&amp;gt;ac5 = (buf[8] &amp;lt;&amp;lt; 8) | buf[9];
    d-&amp;gt;ac6 = (buf[10] &amp;lt;&amp;lt; 8) | buf[11];
    d-&amp;gt;b1  = (buf[12] &amp;lt;&amp;lt; 8) | buf[13];
    d-&amp;gt;b2  = (buf[14] &amp;lt;&amp;lt; 8) | buf[15];
    d-&amp;gt;mb  = (buf[16] &amp;lt;&amp;lt; 8) | buf[17];
    d-&amp;gt;mc  = (buf[18] &amp;lt;&amp;lt; 8) | buf[19];
    d-&amp;gt;md  = (buf[20] &amp;lt;&amp;lt; 8) | buf[21];
    return 0;
}

static int bmp180_read_raw_temp(struct bmp180_data *d, int *ut)
{
    int ret;
    u8 msb, lsb;

    /* Send temperature measurement command */
    ret = i2c_smbus_write_byte_data(d-&amp;gt;client,
                                    BMP180_REG_CTRL,
                                    BMP180_CMD_TEMP);
    if (ret &amp;lt; 0)
        return ret;
    msleep(5);

    /* Read MSB and LSB directly from DATA registers */
    msb = i2c_smbus_read_byte_data(d-&amp;gt;client, BMP180_REG_DATA);
    lsb = i2c_smbus_read_byte_data(d-&amp;gt;client, BMP180_REG_DATA + 1);
    if ((int)msb &amp;lt; 0 || (int)lsb &amp;lt; 0)
        return -EIO;

    *ut = (msb &amp;lt;&amp;lt; 8) | lsb;
    return 0;
}

static int bmp180_read_raw_press(struct bmp180_data *d, int *up)
{
    int ret;
    u8 msb, lsb, xlsb;

    ret = i2c_smbus_write_byte_data(d-&amp;gt;client,
                                    BMP180_REG_CTRL,
                                    BMP180_CMD_PRESS + (d-&amp;gt;oss &amp;lt;&amp;lt; 6));
    if (ret &amp;lt; 0)
        return ret;
    msleep(5 + (3 &amp;lt;&amp;lt; d-&amp;gt;oss));

    msb  = i2c_smbus_read_byte_data(d-&amp;gt;client, BMP180_REG_DATA);
    lsb  = i2c_smbus_read_byte_data(d-&amp;gt;client, BMP180_REG_DATA + 1);
    xlsb = i2c_smbus_read_byte_data(d-&amp;gt;client, BMP180_REG_DATA + 2);
    if ((int)msb &amp;lt; 0 || (int)lsb &amp;lt; 0 || (int)xlsb &amp;lt; 0)
        return -EIO;

    *up = ((msb &amp;lt;&amp;lt; 16) | (lsb &amp;lt;&amp;lt; 8) | xlsb) &amp;gt;&amp;gt; (8 - d-&amp;gt;oss);
    return 0;
}

static long bmp180_calc_temp(struct bmp180_data *d, int ut, int *t)
{
    long x1 = ((long)ut - d-&amp;gt;ac6) * d-&amp;gt;ac5 &amp;gt;&amp;gt; 15;
    long x2 = ((long)d-&amp;gt;mc &amp;lt;&amp;lt; 11) / (x1 + d-&amp;gt;md);
    long b5 = x1 + x2;

    *t = (b5 + 8) &amp;gt;&amp;gt; 4;  /* 0.1&amp;deg;C unit */
    return b5;
}

static int bmp180_calc_press(struct bmp180_data *d, int up,
                             long b5, int *p)
{
    long b6 = b5 - 4000;
    long x1 = (d-&amp;gt;b2 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 11;
    long x2 = (d-&amp;gt;ac2 * b6) &amp;gt;&amp;gt; 11;
    long x3 = x1 + x2;
    long b3 = ((((long)d-&amp;gt;ac1 * 4 + x3) &amp;lt;&amp;lt; d-&amp;gt;oss) + 2) &amp;gt;&amp;gt; 2;
    x1 = (d-&amp;gt;ac3 * b6) &amp;gt;&amp;gt; 13;
    x2 = (d-&amp;gt;b1 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 16;
    x3 = ((x1 + x2) + 2) &amp;gt;&amp;gt; 2;
    long b4 = (d-&amp;gt;ac4 * (unsigned long)(x3 + 32768)) &amp;gt;&amp;gt; 15;
    long b7 = ((unsigned long)up - b3) * (50000 &amp;gt;&amp;gt; d-&amp;gt;oss);
    long p_raw = (b7 &amp;lt; 0x80000000 ?
                  (b7 &amp;lt;&amp;lt; 1) / b4 :
                  (b7 / b4) &amp;lt;&amp;lt; 1);
    x1 = (p_raw &amp;gt;&amp;gt; 8) * (p_raw &amp;gt;&amp;gt; 8);
    x1 = (x1 * 3038) &amp;gt;&amp;gt; 16;
    x2 = (-7357 * p_raw) &amp;gt;&amp;gt; 16;
    *p = p_raw + ((x1 + x2 + 3791) &amp;gt;&amp;gt; 4);

    return 0;
}

/* sysfs show functions */
static ssize_t show_temp(struct device *dev,
                         struct device_attribute *attr,
                         char *buf)
{
    struct bmp180_data *d = dev_get_drvdata(dev);
    int ut, t, ret;
    long b5;

    mutex_lock(&amp;amp;d-&amp;gt;lock);
    ret = bmp180_read_raw_temp(d, &amp;amp;ut);
    if (ret &amp;lt; 0)
        goto out;
    b5 = bmp180_calc_temp(d, ut, &amp;amp;t);
out:
    mutex_unlock(&amp;amp;d-&amp;gt;lock);

    if (ret &amp;lt; 0)
        return ret;
    return sprintf(buf, &quot;%d\n&quot;, t);
}
static DEVICE_ATTR(temp, 0444, show_temp, NULL);

static ssize_t show_press(struct device *dev,
                          struct device_attribute *attr,
                          char *buf)
{
    struct bmp180_data *d = dev_get_drvdata(dev);
    int ut, up, p, ret;
    long b5;

    mutex_lock(&amp;amp;d-&amp;gt;lock);
    ret = bmp180_read_raw_temp(d, &amp;amp;ut);
    if (ret &amp;lt; 0)
        goto out;
    b5 = bmp180_calc_temp(d, ut, &amp;amp;p);
    ret = bmp180_read_raw_press(d, &amp;amp;up);
    if (ret &amp;lt; 0)
        goto out;
    ret = bmp180_calc_press(d, up, b5, &amp;amp;p);
out:
    mutex_unlock(&amp;amp;d-&amp;gt;lock);

    if (ret &amp;lt; 0)
        return ret;
    return sprintf(buf, &quot;%d\n&quot;, p);
}
static DEVICE_ATTR(pressure, 0444, show_press, NULL);

static struct attribute *bmp180_attrs[] = {
    &amp;amp;dev_attr_temp.attr,
    &amp;amp;dev_attr_pressure.attr,
    NULL,
};
static const struct attribute_group bmp180_group = {
    .attrs = bmp180_attrs,
};

static const struct of_device_id bmp180_of_match[] = {
    { .compatible = &quot;bosch,bmp180&quot; },
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, bmp180_of_match);

static const struct i2c_device_id bmp180_id[] = {
    { &quot;bmp180&quot;, 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, bmp180_id);

static int bmp180_probe(struct i2c_client *client)
{
    struct bmp180_data *d;
    int ret;

    d = devm_kzalloc(&amp;amp;client-&amp;gt;dev,
                     sizeof(*d), GFP_KERNEL);
    if (!d)
        return -ENOMEM;

    mutex_init(&amp;amp;d-&amp;gt;lock);
    d-&amp;gt;client = client;
    d-&amp;gt;oss    = 0;
    i2c_set_clientdata(client, d);

    ret = bmp180_read_calib(d);
    if (ret &amp;lt; 0) {
        dev_err(&amp;amp;client-&amp;gt;dev,
                &quot;calibration read failed: %d\n&quot;, ret);
        return ret;
    }

    ret = sysfs_create_group(&amp;amp;client-&amp;gt;dev.kobj,
                             &amp;amp;bmp180_group);
    if (ret)
        dev_err(&amp;amp;client-&amp;gt;dev,
                &quot;sysfs group create failed: %d\n&quot;, ret);

    dev_info(&amp;amp;client-&amp;gt;dev, &quot;BMP180 sensor probed\n&quot;);
    return ret;
}

static void bmp180_remove(struct i2c_client *client)
{
    sysfs_remove_group(&amp;amp;client-&amp;gt;dev.kobj,
                       &amp;amp;bmp180_group);
}

static struct i2c_driver bmp180_driver = {
    .driver = {
        .name           = &quot;bmp180&quot;,
        .of_match_table = of_match_ptr(bmp180_of_match),
    },
    .probe    = bmp180_probe,
    .remove   = bmp180_remove,
    .id_table = bmp180_id,
};
module_i2c_driver(bmp180_driver);

MODULE_AUTHOR(&quot;Your Name&quot;);
MODULE_DESCRIPTION(&quot;BMP180 pressure/temperature sensor driver&quot;);
MODULE_LICENSE(&quot;GPL v2&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응용프로그램 개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bmp180_read.c&lt;/p&gt;
&lt;pre id=&quot;code_1750751732962&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bmp180_read.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;dirent.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;

#define I2C_DEV_DIR   &quot;/sys/bus/i2c/devices&quot;
#define TEMP_FILE     &quot;temp&quot;
#define PRESS_FILE    &quot;pressure&quot;

// 디렉토리 안에 temp와 pressure 파일이 모두 있는 첫 번째 디렉토리 검색
static int find_bmp180_dir(char *out, size_t len) {
    DIR *d = opendir(I2C_DEV_DIR);
    struct dirent *ent;
    if (!d) return -1;

    while ((ent = readdir(d)) != NULL) {
        // 디렉토리 이름이 &quot;버스-주소&quot; 형태인지 간단히 체크
        if (strchr(ent-&amp;gt;d_name, '-') == NULL) 
            continue;

        char path_temp[256], path_press[256];
        snprintf(path_temp,  sizeof(path_temp),
                 I2C_DEV_DIR &quot;/%s/&quot; TEMP_FILE, ent-&amp;gt;d_name);
        snprintf(path_press, sizeof(path_press),
                 I2C_DEV_DIR &quot;/%s/&quot; PRESS_FILE, ent-&amp;gt;d_name);

        if (access(path_temp, R_OK) == 0 &amp;amp;&amp;amp; access(path_press, R_OK) == 0) {
            snprintf(out, len, I2C_DEV_DIR &quot;/%s&quot;, ent-&amp;gt;d_name);
            closedir(d);
            return 0;
        }
    }

    closedir(d);
    return -1;
}

// sysfs에서 정수 읽기
static int read_int(const char *path, int *out) {
    char buf[32];
    int fd = open(path, O_RDONLY);
    if (fd &amp;lt; 0) return -1;
    ssize_t n = read(fd, buf, sizeof(buf)-1);
    close(fd);
    if (n &amp;lt;= 0) return -1;
    buf[n] = '\0';
    *out = atoi(buf);
    return 0;
}

int main(void) {
    char devdir[128];
    if (find_bmp180_dir(devdir, sizeof(devdir)) &amp;lt; 0) {
        fprintf(stderr, &quot;ERROR: bmp180 모듈 디렉토리를 찾을 수 없습니다.\n&quot;);
        return 1;
    }

    char temp_path[256], press_path[256];
    snprintf(temp_path,  sizeof(temp_path),
             &quot;%s/&quot; TEMP_FILE,  devdir);
    snprintf(press_path, sizeof(press_path),
             &quot;%s/&quot; PRESS_FILE, devdir);

    printf(&quot;BMP180 기압&amp;middot;온도 측정 (Ctrl+C로 종료)\n\n&quot;);
    while (1) {
        int t_raw, p_raw;
        if (read_int(temp_path,  &amp;amp;t_raw) &amp;lt; 0 ||
            read_int(press_path, &amp;amp;p_raw) &amp;lt; 0) {
            fprintf(stderr,
                &quot;센서 값 읽기 실패: %s\n&quot;,
                strerror(errno));
            return 1;
        }

        // 모듈에서 temp는 0.1&amp;deg;C 단위로, pressure는 Pa 단위로 리턴됩니다.
        double temp_c = t_raw / 10.0;
        double press_hpa = p_raw / 100.0;

        printf(&quot;온도: %.1f &amp;deg;C    압력: %.2f hPa\n&quot;,
               temp_c, press_hpa);
        sleep(1);
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;347&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCqqnN/btsOQbLsuGL/Bw0urKiYFkOQLbT4ZkPpLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCqqnN/btsOQbLsuGL/Bw0urKiYFkOQLbT4ZkPpLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCqqnN/btsOQbLsuGL/Bw0urKiYFkOQLbT4ZkPpLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCqqnN%2FbtsOQbLsuGL%2FBw0urKiYFkOQLbT4ZkPpLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;347&quot; height=&quot;327&quot; data-origin-width=&quot;347&quot; data-origin-height=&quot;327&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/525</guid>
      <comments>https://hotari.tistory.com/525#entry525comment</comments>
      <pubDate>Tue, 24 Jun 2025 16:57:19 +0900</pubDate>
    </item>
    <item>
      <title>9일차</title>
      <link>https://hotari.tistory.com/524</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.23&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctags&lt;/p&gt;
&lt;pre id=&quot;code_1750638373077&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo apt-get install universal-ctags
$ sudo apt-get install cscope

#linux 폴더에서 실행

ctags -R
cscope -R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1750638384278&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vi ~/.vimrc&amp;nbsp;&amp;nbsp; 로 .vimrc 파일을 연다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1750638378993&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set hlsearch
set autoindent
set cindent
set nu
set tabstop=4 
set shiftwidth=4
set title
if has(&quot;syntax&quot;)
    syntax on
endif


if filereadable(&quot;./tags&quot;)
    set tags=./tags
elseif filereadable(&quot;../tags&quot;)
    set tags=../tags
elseif filereadable(&quot;../../tags&quot;)
    set tags=../../tags
elseif filereadable(&quot;../../../tags&quot;)
    set tags=../../../tags
elseif filereadable(&quot;../../../../tags&quot;)
    set tags=../../../../tags
else
    set tags=/home/ubuntu/project/linux/tags
endif

set tags=/home/ubuntu/project/linux/tags

set csprg=/usr/bin/cscope
&quot;set csto=0
&quot;set cst
set nocsverb
if filereadable(&quot;./cscope.out&quot;)
    cs add ./cscope.out
elseif filereadable(&quot;../cscope.out&quot;)
    cs add ../cscope.out
elseif filereadable(&quot;../../cscope.out&quot;)
    cs add ../../cscope.out
elseif filereadable(&quot;../../../cscope.out&quot;)
    cs add ../../../cscope.out
elseif filereadable(&quot;../../../../cscope.out&quot;)
    cs add ../../../../cscope.out
else
    cs add /home/pi/project/linux/cscope.out
endif
set csverb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정의로 가기&lt;/p&gt;
&lt;pre id=&quot;code_1750638491724&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Ctrl-] 

Ctrl-t

gd =&amp;gt; go definition

Ctrl+o to go back; Ctrl+i to go forward&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;search 현재 커서있는 단어&lt;/p&gt;
&lt;pre id=&quot;code_1750639005462&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;g + *

n : next 찾기
shift + n : previous
Ctrl+o to go back; Ctrl+i to go forward&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;line number로 이동&lt;/p&gt;
&lt;pre id=&quot;code_1750639021754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;50 + shift + g&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;word로 이동&lt;/p&gt;
&lt;pre id=&quot;code_1750639033677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;7 + w&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[cscope 사용법]
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;소스 디렉토리에서 ctags 생성&lt;/li&gt;
&lt;/ol&gt;
분석하려는 소스들의 루트 디렉토리에서 생성
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;$ ctags -R
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-R 이라는 옵션이 하위디렉토리까지 생각해서 만든다는거다.&lt;/li&gt;
&lt;li&gt;만약에 ctags * 라고 명령어를 실행하면, 현재 디렉토리 기준으로만 ctag가 생성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;소스 디렉토리에서 cscope.out 과 cscope.files 를 생성&lt;/li&gt;
&lt;/ol&gt;
즉, 내가 분석하려는 소스들의 루트 디렉토리에서 생성
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;$ cscope -R
&lt;/code&gt;&lt;/pre&gt;
ctrl + d 눌러서 빠져 나온다.&lt;/li&gt;
&lt;li&gt;ex) 만약에 test/ 즉, test라는 폴더 안의 소스를 전부 분석하고 싶으면 cd test 로 test 폴더 들어가서 만들면 되겠지.&lt;/li&gt;
&lt;li&gt;ex) 만약에 test/ 즉, test라는 폴더 안의 소스를 전부 분석하고 싶으면 cd test 로 test 폴더 들어가서 만들면 되겠지.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핸들러 함수 VS 콜백 함수&lt;/p&gt;
&lt;table id=&quot;21ac5962-3e61-806a-91fa-cc7ea3b6a77e&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr id=&quot;21ac5962-3e61-807b-a91c-f4cc01d478a0&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;구분&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;핸들러 함수 (Handler Function)&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;콜백 함수 (Callback Function)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;21ac5962-3e61-8052-a201-efd3a58b8cfe&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;&lt;b&gt;정의&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;특정 이벤트나 신호, 인터럽트 등이 발생했을 때 이를 처리하기 위해 등록된 함수&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;다른 함수에 인자로 전달되어, 특정 조건이나 이벤트 발생 시 호출되는 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;21ac5962-3e61-80e6-8dc8-f1a95cdd5ba0&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;&lt;b&gt;주요 용도&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;주로 이벤트, 인터럽트, 신호, 사용자 입력 등을 처리하는 데 사용&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;비동기 처리, 이벤트 처리, 작업 완료 시 추가 동작 등 다양한 상황에서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;21ac5962-3e61-808b-9bf8-cbc05958b317&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;&lt;b&gt;등록 방식&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;시스템이나 프레임워크에 핸들러로 명시적으로 등록됨 (예: 인터럽트 핸들러, 이벤트 핸들러)&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;함수의 인자로 직접 전달되거나, 내부적으로 등록되어 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;21ac5962-3e61-8023-956b-dc6187572071&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;&lt;b&gt;실행 시점&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;해당 이벤트나 신호가 발생할 때 시스템이 자동으로 호출&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;해당 함수(예: 비동기 함수)의 작업이 끝나거나, 특정 조건이 만족될 때 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;21ac5962-3e61-809f-9330-dbc47149a9b9&quot;&gt;
&lt;td id=&quot;M&amp;gt;sj&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;|zGb&quot;&gt;인터럽트 핸들러, 이벤트 핸들러, 신호 핸들러&lt;/td&gt;
&lt;td id=&quot;Xw:o&quot;&gt;setTimeout, 비동기 파일 읽기, Promise.then, 이벤트 리스너 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;추가 설명&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;핸들러 함수&lt;/b&gt;는 &amp;ldquo;어떤 이벤트나 신호가 발생했을 때 그에 대응해 처리하는 역할&amp;rdquo;을 하며, 운영체제나 프레임워크에 명시적으로 등록되어 동작합니다. 예를 들어, 인터럽트 핸들러는 하드웨어 인터럽트가 발생할 때 운영체제가 호출하는 함수입니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;콜백 함수&lt;/b&gt;는 &amp;ldquo;다른 함수에 인자로 전달되어, 그 함수의 작업이 끝난 후에 호출되는 함수&amp;rdquo;입니다. 콜백은 비동기 처리, 이벤트 처리 등에서 널리 사용되며, 함수의 제어 흐름을 유연하게 만들 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;관계&lt;/b&gt;: 콜백 함수가 핸들러로 등록되어 사용될 수도 있습니다. 예를 들어, 이벤트 핸들러를 콜백 함수로 등록하는 경우가 많습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;핸들러 함수&lt;/b&gt;: 이벤트나 신호가 발생할 때 시스템이 자동으로 호출하도록 등록된 함수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;콜백 함수&lt;/b&gt;: 다른 함수에 인자로 전달되어, 특정 조건이나 이벤트가 발생할 때 호출되는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘은 비슷해 보이지만, 핸들러는 &amp;ldquo;등록&amp;rdquo;과 &amp;ldquo;자동 호출&amp;rdquo;에 초점이 있고, 콜백은 &amp;ldquo;함수 전달&amp;rdquo;과 &amp;ldquo;유연한 실행&amp;rdquo;에 초점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;1. list_add() / list_add_tail()&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;void list_add(struct list_head *new, struct list_head *head);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;void list_add_tail(struct list_head *new, struct list_head *head);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; 첫 번째 인자: new &amp;rarr; 새로 리스트에 넣을 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; 두 번째 인자: head &amp;rarr; 어디 근처에 넣을지를 결정하는 기준&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 이 함수는 new를 어디에 &amp;ldquo;넣을지&amp;rdquo; 결정하기 때문에, new가 주체입니다.&lt;/b&gt;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;2. list_del() / list_move()&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;void list_del(struct list_head *entry);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;void list_move(struct list_head *entry, struct list_head *head);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; 첫 번째 인자: entry &amp;rarr; 이미 리스트 안에 존재하는 노드 (작업의 대상)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; list_del(entry) &amp;rarr; entry를 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; list_move(entry, head) &amp;rarr; entry를 head 바로 뒤로 이동&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 함수들은 리스트에 이미 들어 있는 노드를 조작하는 것이기 때문에, 그 노드가 첫 번째 인자로 오는 것이 자연스럽습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;요약 표&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수 이름&lt;/b&gt; &lt;b&gt;첫 번째 인자&lt;/b&gt; &lt;b&gt;의미&lt;/b&gt; &lt;b&gt;동작 주체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;list_add()&lt;/b&gt; &lt;b&gt;new&lt;/b&gt; &lt;b&gt;새로 추가할 노드&lt;/b&gt; &lt;b&gt;추가 대상 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;list_add_tail()&lt;/b&gt; &lt;b&gt;new&lt;/b&gt; &lt;b&gt;새로 추가할 노드&lt;/b&gt; &lt;b&gt;추가 대상 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;list_del()&lt;/b&gt; &lt;b&gt;entry&lt;/b&gt; &lt;b&gt;삭제할 노드&lt;/b&gt; &lt;b&gt;조작 대상 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;list_move()&lt;/b&gt; &lt;b&gt;entry&lt;/b&gt; &lt;b&gt;이동시킬 노드&lt;/b&gt; &lt;b&gt;조작 대상 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;list_move_tail()&lt;/b&gt; &lt;b&gt;entry&lt;/b&gt; &lt;b&gt;리스트의 끝으로 이동시킬 노드&lt;/b&gt; &lt;b&gt;조작 대상 노드&lt;/b&gt;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;비유로 이해하기&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; list_add(new, head)는 &amp;ldquo;new야, 너 head 뒤에 가 있어&amp;rdquo; &amp;rarr; new가 중심&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; list_del(entry)는 &amp;ldquo;entry야, 너 삭제당해&amp;rdquo; &amp;rarr; entry가 중심&lt;/b&gt;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;보통 이런 설계는 왜 하나요?&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; 일관성 유지와 가독성 때문입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;bull; 보통 어떤 함수가 무엇을 조작할지에 따라 그 &amp;ldquo;주체&amp;rdquo;를 첫 번째 인자로 넣는 것이 일반적입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qWGwQ/btsONcc73Rn/8L809c47w69PEujU30lidK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qWGwQ/btsONcc73Rn/8L809c47w69PEujU30lidK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qWGwQ/btsONcc73Rn/8L809c47w69PEujU30lidK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqWGwQ%2FbtsONcc73Rn%2F8L809c47w69PEujU30lidK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;272&quot; height=&quot;134&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bh1750.c&lt;/p&gt;
&lt;pre id=&quot;code_1750660412426&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* bh1750_chrdrv.c */

#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/i2c.h&amp;gt;
#include &amp;lt;linux/delay.h&amp;gt;
#include &amp;lt;linux/slab.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;
#include &amp;lt;linux/cdev.h&amp;gt;
#include &amp;lt;linux/device.h&amp;gt;

#define BH1750_ADDR      0x23
#define CMD_POWER_ON     0x01
#define CMD_RESET        0x07
#define CMD_CONT_HIGHRES 0x10

#define DEVICE_NAME      &quot;bh1750&quot;
#define CLASS_NAME       &quot;sensor&quot;

struct bh1750_data {
    struct i2c_client *client;
    struct cdev cdev;
};

static dev_t dev_number;
static struct class *bh1750_class;

static int bh1750_read_lux(struct i2c_client *client, char *buf)
{
    u8 data[2];
    int ret;
    u16 raw;
    u32 lux_x100;

    /* 전원 ON, 리셋, 연속 고해상도 모드 */
    i2c_smbus_write_byte(client, CMD_POWER_ON);
    i2c_smbus_write_byte(client, CMD_RESET);
    i2c_smbus_write_byte(client, CMD_CONT_HIGHRES);
    msleep(180);

    ret = i2c_smbus_read_i2c_block_data(client,
                                        CMD_CONT_HIGHRES,
                                        2, data);
    if (ret &amp;lt; 0)
        return ret;

    raw = (data[0] &amp;lt;&amp;lt; 8) | data[1];
    lux_x100 = (raw * 1000U + 6) / 12;

    return sprintf(buf, &quot;%u.%02u\n&quot;,
                   lux_x100 / 100,
                   lux_x100 % 100);
}

static ssize_t bh1750_char_read(struct file *filp,
                                char __user *user_buf,
                                size_t count,
                                loff_t *ppos)
{
    struct bh1750_data *d = filp-&amp;gt;private_data;
    char tmp[16];
    int len;

    if (*ppos &amp;gt; 0)
        return 0; /* EOF */

    len = bh1750_read_lux(d-&amp;gt;client, tmp);
    if (len &amp;lt; 0)
        return len;

    if (copy_to_user(user_buf, tmp, len))
        return -EFAULT;

    *ppos += len;
    return len;
}

static int bh1750_char_open(struct inode *inode, struct file *filp)
{
    struct bh1750_data *d = container_of(inode-&amp;gt;i_cdev,
                                         struct bh1750_data, cdev);
    filp-&amp;gt;private_data = d;
    return 0;
}

static const struct file_operations bh1750_fops = {
    .owner   = THIS_MODULE,
    .open    = bh1750_char_open,
    .read    = bh1750_char_read,
};

static int bh1750_probe(struct i2c_client *client)
{
    struct bh1750_data *d;
    int ret;

    /* 드라이버 데이터 할당 */
    d = devm_kzalloc(&amp;amp;client-&amp;gt;dev, sizeof(*d), GFP_KERNEL);
    if (!d)
        return -ENOMEM;
    d-&amp;gt;client = client;

    /* 캐릭터 디바이스 번호 및 클래스 생성 */
    if (!bh1750_class) {
        ret = alloc_chrdev_region(&amp;amp;dev_number, 0, 1, DEVICE_NAME);
        if (ret &amp;lt; 0)
            return ret;

        bh1750_class = class_create(CLASS_NAME);
        if (IS_ERR(bh1750_class)) {
            unregister_chrdev_region(dev_number, 1);
            return PTR_ERR(bh1750_class);
        }
    }

    /* cdev 초기화 및 등록 */
    cdev_init(&amp;amp;d-&amp;gt;cdev, &amp;amp;bh1750_fops);
    d-&amp;gt;cdev.owner = THIS_MODULE;
    ret = cdev_add(&amp;amp;d-&amp;gt;cdev, dev_number, 1);
    if (ret) {
        class_destroy(bh1750_class);
        unregister_chrdev_region(dev_number, 1);
        return ret;
    }

    /* /dev 노드 생성 */
    device_create(bh1750_class, NULL, dev_number, NULL, DEVICE_NAME);

    i2c_set_clientdata(client, d);
    dev_info(&amp;amp;client-&amp;gt;dev, &quot;%s: registered char device /dev/%s\n&quot;,
             DEVICE_NAME, DEVICE_NAME);
    return 0;
}

static void bh1750_remove(struct i2c_client *client)
{
    struct bh1750_data *d = i2c_get_clientdata(client);

    device_destroy(bh1750_class, dev_number);
    cdev_del(&amp;amp;d-&amp;gt;cdev);
    class_destroy(bh1750_class);
    unregister_chrdev_region(dev_number, 1);
}

static const struct i2c_device_id bh1750_id[] = {
    { &quot;bh1750&quot;, 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, bh1750_id);

static struct i2c_driver bh1750_driver = {
    .driver   = { .name = &quot;bh1750&quot; },
    .probe    = bh1750_probe,
    .remove   = bh1750_remove,
    .id_table = bh1750_id,
};

module_i2c_driver(bh1750_driver);

MODULE_AUTHOR(&quot;Your Name&quot;);
MODULE_DESCRIPTION(&quot;BH1750 I2C Light Sensor with /dev Interface&quot;);
MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/52SYM/btsOLROAsXZ/KsECADBzU1HqModmqtjXeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/52SYM/btsOLROAsXZ/KsECADBzU1HqModmqtjXeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/52SYM/btsOLROAsXZ/KsECADBzU1HqModmqtjXeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F52SYM%2FbtsOLROAsXZ%2FKsECADBzU1HqModmqtjXeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;929&quot; height=&quot;287&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVba7H/btsOOcpVw87/hFOrJPXPktigEiL7VT4AY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVba7H/btsOOcpVw87/hFOrJPXPktigEiL7VT4AY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVba7H/btsOOcpVw87/hFOrJPXPktigEiL7VT4AY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVba7H%2FbtsOOcpVw87%2FhFOrJPXPktigEiL7VT4AY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;201&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;201&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGercw/btsOLQPMbdA/2i3ZsQF9aVXdhCL4ZbmfNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGercw/btsOLQPMbdA/2i3ZsQF9aVXdhCL4ZbmfNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGercw/btsOLQPMbdA/2i3ZsQF9aVXdhCL4ZbmfNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGercw%2FbtsOLQPMbdA%2F2i3ZsQF9aVXdhCL4ZbmfNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;213&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bh1750_read.c&lt;/p&gt;
&lt;pre id=&quot;code_1750660512624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bh1750_read.c (using sysfs interface, continuous measurement)
// 유저스페이스에서 sysfs로 BH1750 조도 센서 값을 계속 읽어 출력

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int main(void) {
    const char *sysfs_path = &quot;/dev/bh1750&quot;;
    char buf[32];

    while (1) {
        FILE *fp = fopen(sysfs_path, &quot;r&quot;);
        if (!fp) {
            perror(&quot;fopen sysfs lux&quot;);
            return EXIT_FAILURE;
        }

        if (fgets(buf, sizeof(buf), fp) != NULL) {
            size_t len = strlen(buf);
            if (len &amp;gt; 0 &amp;amp;&amp;amp; buf[len-1] == '\n')
                buf[len-1] = '\0';
            printf(&quot;Ambient Light: %s lux\n&quot;, buf);
        } else {
            fprintf(stderr, &quot;Failed to read lux value from %s\n&quot;, sysfs_path);
            fclose(fp);
            return EXIT_FAILURE;
        }

        fclose(fp);
        sleep(1); // 1초 간격으로 측정
    }

    return EXIT_SUCCESS;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I2gjj/btsOLRgQcad/1q4k3QyjTu7naa4ADBA0x1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I2gjj/btsOLRgQcad/1q4k3QyjTu7naa4ADBA0x1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I2gjj/btsOLRgQcad/1q4k3QyjTu7naa4ADBA0x1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2gjj%2FbtsOLRgQcad%2F1q4k3QyjTu7naa4ADBA0x1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;283&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 data-end=&quot;116&quot; data-start=&quot;98&quot;&gt;1. 모듈 등록 및 메타 정보&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663915412&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module_i2c_driver(bh1750_driver);

MODULE_AUTHOR(&quot;Your Name&quot;);
MODULE_DESCRIPTION(&quot;BH1750 I2C Light Sensor with /dev Interface&quot;);
MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;537&quot; data-start=&quot;281&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;413&quot; data-start=&quot;281&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;413&quot; data-start=&quot;297&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;365&quot; data-start=&quot;297&quot;&gt;module_init/module_exit 대신 버스 전용 매크로(module_i2c_driver) 사용&lt;/li&gt;
&lt;li data-end=&quot;413&quot; data-start=&quot;368&quot;&gt;MODULE_LICENSE(&quot;GPL&quot;) 등으로 라이선스&amp;middot;저자&amp;middot;설명 기입&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;537&quot; data-start=&quot;414&quot;&gt;&lt;b&gt;bh1750_chrdrv.c&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;537&quot; data-start=&quot;440&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;474&quot; data-start=&quot;440&quot;&gt;I&amp;sup2;C 버스에 붙는 bh1750_driver를 등록&lt;/li&gt;
&lt;li data-end=&quot;537&quot; data-start=&quot;477&quot;&gt;모듈이 로드될 때 bh1750_probe 호출, 언로드될 때 자동으로 bh1750_remove&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;542&quot; data-start=&quot;539&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;561&quot; data-start=&quot;544&quot;&gt;2. I&amp;sup2;C 드라이버 구조체&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663923402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static const struct i2c_device_id bh1750_id[] = {
    { &quot;bh1750&quot;, 0 },
    { }
};

static struct i2c_driver bh1750_driver = {
    .driver   = { .name = &quot;bh1750&quot; },
    .probe    = bh1750_probe,
    .remove   = bh1750_remove,
    .id_table = bh1750_id,
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;996&quot; data-start=&quot;828&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;915&quot; data-start=&quot;828&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;915&quot; data-start=&quot;844&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;878&quot; data-start=&quot;844&quot;&gt;.name / .id_table로 디바이스 매칭&lt;/li&gt;
&lt;li data-end=&quot;915&quot; data-start=&quot;881&quot;&gt;.probe() / .remove() 콜백 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;996&quot; data-start=&quot;916&quot;&gt;&lt;b&gt;적용 예&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;996&quot; data-start=&quot;931&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;996&quot; data-start=&quot;931&quot;&gt;디바이스 트리나 i2c_board_info에서 &quot;bh1750&quot;가 있으면 bh1750_probe 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1001&quot; data-start=&quot;998&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1019&quot; data-start=&quot;1003&quot;&gt;3. 드라이버 데이터 저장&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663930977&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct bh1750_data {
    struct i2c_client *client;
    struct cdev       cdev;
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1296&quot; data-start=&quot;1114&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1215&quot; data-start=&quot;1114&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1215&quot; data-start=&quot;1130&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1162&quot; data-start=&quot;1130&quot;&gt;디바이스별 컨텍스트(struct)에 상태&amp;middot;핸들 저장&lt;/li&gt;
&lt;li data-end=&quot;1215&quot; data-start=&quot;1165&quot;&gt;devm_kzalloc() / i2c_set_clientdata() 로 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1296&quot; data-start=&quot;1216&quot;&gt;&lt;b&gt;코드 내역&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1296&quot; data-start=&quot;1232&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1261&quot; data-start=&quot;1232&quot;&gt;client 포인터 &amp;rarr; I&amp;sup2;C 전송에 사용&lt;/li&gt;
&lt;li data-end=&quot;1296&quot; data-start=&quot;1264&quot;&gt;cdev 구조체 &amp;rarr; 캐릭터 디바이스 등록에 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1301&quot; data-start=&quot;1298&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1319&quot; data-start=&quot;1303&quot;&gt;4. 캐릭터 디바이스 등록&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663939031&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 1) dev 번호 할당 &amp;amp; class 생성 */
ret = alloc_chrdev_region(&amp;amp;dev_number, 0, 1, DEVICE_NAME);
bh1750_class = class_create(CLASS_NAME);

/* 2) cdev 초기화 &amp;amp; 등록 */
cdev_init(&amp;amp;d-&amp;gt;cdev, &amp;amp;bh1750_fops);
cdev_add(&amp;amp;d-&amp;gt;cdev, dev_number, 1);

/* 3) /dev 노드 생성 */
device_create(bh1750_class, NULL, dev_number, NULL, DEVICE_NAME);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1902&quot; data-start=&quot;1642&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1785&quot; data-start=&quot;1642&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1785&quot; data-start=&quot;1658&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1686&quot; data-start=&quot;1658&quot;&gt;alloc_chrdev_region()&lt;/li&gt;
&lt;li data-end=&quot;1722&quot; data-start=&quot;1689&quot;&gt;cdev_init() + cdev_add()&lt;/li&gt;
&lt;li data-end=&quot;1785&quot; data-start=&quot;1725&quot;&gt;class_create() + device_create() &amp;rarr; /dev/... 자동 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1902&quot; data-start=&quot;1786&quot;&gt;&lt;b&gt;주의 사항&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1902&quot; data-start=&quot;1802&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1857&quot; data-start=&quot;1802&quot;&gt;class_create() 시점에 THIS_MODULE 인자는 최신 API에서 제거됨&lt;/li&gt;
&lt;li data-end=&quot;1902&quot; data-start=&quot;1860&quot;&gt;성공 시 major/minor 번호가 dev_number에 채워짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1907&quot; data-start=&quot;1904&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1937&quot; data-start=&quot;1909&quot;&gt;5. 파일 연산자(File Operations)&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663946022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static const struct file_operations bh1750_fops = {
    .owner = THIS_MODULE,
    .open  = bh1750_char_open,
    .read  = bh1750_char_read,
};&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2327&quot; data-start=&quot;2092&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2217&quot; data-start=&quot;2092&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2217&quot; data-start=&quot;2108&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2157&quot; data-start=&quot;2108&quot;&gt;open, read, write, ioctl 등 함수 포인터 테이블&lt;/li&gt;
&lt;li data-end=&quot;2217&quot; data-start=&quot;2160&quot;&gt;사용자 공간의 open(&quot;/dev/bh1750&quot;) &amp;rarr; bh1750_char_open 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2327&quot; data-start=&quot;2218&quot;&gt;&lt;b&gt;bh1750_chrdrv.c&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2327&quot; data-start=&quot;2244&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2293&quot; data-start=&quot;2244&quot;&gt;open에서 private_data에 bh1750_data 구조체 연결&lt;/li&gt;
&lt;li data-end=&quot;2327&quot; data-start=&quot;2296&quot;&gt;read에서 I&amp;sup2;C 센서값을 읽어 버퍼에 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2332&quot; data-start=&quot;2329&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2359&quot; data-start=&quot;2334&quot;&gt;6. I&amp;sup2;C 통신: SMBus API 사용&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663955296&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;i2c_smbus_write_byte(client, CMD_POWER_ON);
i2c_smbus_write_byte(client, CMD_RESET);
i2c_smbus_write_byte(client, CMD_CONT_HIGHRES);
msleep(180);
i2c_smbus_read_i2c_block_data(client, CMD_CONT_HIGHRES, 2, data);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2710&quot; data-start=&quot;2583&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2634&quot; data-start=&quot;2583&quot;&gt;&lt;b&gt;일반 원리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2634&quot; data-start=&quot;2599&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2634&quot; data-start=&quot;2599&quot;&gt;SMBus API로 간단한 바이트 송수신 또는 블록 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2710&quot; data-start=&quot;2635&quot;&gt;&lt;b&gt;포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2710&quot; data-start=&quot;2649&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2673&quot; data-start=&quot;2649&quot;&gt;센서에 명령 전송 &amp;rarr; 측정 모드 설정&lt;/li&gt;
&lt;li data-end=&quot;2710&quot; data-start=&quot;2676&quot;&gt;msleep() 사용으로 커널 스케줄러에 제어 양보&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2715&quot; data-start=&quot;2712&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2736&quot; data-start=&quot;2717&quot;&gt;7. Probe &amp;amp; Remove&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750663962791&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static int bh1750_probe(struct i2c_client *client) { &amp;hellip; }
static void bh1750_remove(struct i2c_client *client) { &amp;hellip; }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3106&quot; data-start=&quot;2864&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2988&quot; data-start=&quot;2864&quot;&gt;&lt;b&gt;probe() 주요 작업&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2988&quot; data-start=&quot;2888&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2926&quot; data-start=&quot;2888&quot;&gt;devm_kzalloc()으로 driver data 할당&lt;/li&gt;
&lt;li data-end=&quot;2955&quot; data-start=&quot;2929&quot;&gt;char device 등록 (위 4번)&lt;/li&gt;
&lt;li data-end=&quot;2988&quot; data-start=&quot;2958&quot;&gt;i2c_set_clientdata() 연결&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li data-end=&quot;3106&quot; data-start=&quot;2989&quot;&gt;&lt;b&gt;remove() 주요 작업&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3106&quot; data-start=&quot;3014&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3051&quot; data-start=&quot;3014&quot;&gt;device_destroy(), cdev_del()&lt;/li&gt;
&lt;li data-end=&quot;3106&quot; data-start=&quot;3054&quot;&gt;class_destroy(), unregister_chrdev_region()&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3111&quot; data-start=&quot;3108&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3127&quot; data-start=&quot;3113&quot;&gt;8. 데이터 흐름 요약&lt;/h1&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3332&quot; data-start=&quot;3129&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3159&quot; data-start=&quot;3129&quot;&gt;&lt;b&gt;모듈 로드&lt;/b&gt; &amp;rarr; I&amp;sup2;C driver 등록&lt;/li&gt;
&lt;li data-end=&quot;3196&quot; data-start=&quot;3160&quot;&gt;&lt;b&gt;디바이스 바인딩&lt;/b&gt; &amp;rarr; bh1750_probe()&lt;/li&gt;
&lt;li data-end=&quot;3245&quot; data-start=&quot;3197&quot;&gt;&lt;b&gt;유저 공간&lt;/b&gt;: open(&quot;/dev/bh1750&quot;) &amp;rarr; read()&lt;/li&gt;
&lt;li data-end=&quot;3296&quot; data-start=&quot;3246&quot;&gt;&lt;b&gt;커널&lt;/b&gt;: SMBus 통해 센서 읽고, 포맷팅 후 user buffer에 복사&lt;/li&gt;
&lt;li data-end=&quot;3332&quot; data-start=&quot;3297&quot;&gt;&lt;b&gt;모듈 언로드&lt;/b&gt; &amp;rarr; bh1750_remove()&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;3337&quot; data-start=&quot;3334&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3353&quot; data-start=&quot;3339&quot;&gt;9. 확장 학습 포인트&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3539&quot; data-start=&quot;3355&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3355&quot;&gt;&lt;b&gt;동기 vs 비동기 I/O&lt;/b&gt;: read()가 블로킹/논블로킹 지원해 보기&lt;/li&gt;
&lt;li data-end=&quot;3444&quot; data-start=&quot;3404&quot;&gt;&lt;b&gt;IOCTL 추가&lt;/b&gt;: 측정 모드 변경, 타이밍 조절 기능 구현&lt;/li&gt;
&lt;li data-end=&quot;3495&quot; data-start=&quot;3445&quot;&gt;&lt;b&gt;Device Tree&lt;/b&gt;: .of_match_table 추가하여 DT 바인딩&lt;/li&gt;
&lt;li data-end=&quot;3539&quot; data-start=&quot;3496&quot;&gt;&lt;b&gt;전력 관리&lt;/b&gt;: pm_runtime_* API로 센서 전원 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;16&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;I&amp;sup2;C 주소 스캔 결과에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;343&quot; data-start=&quot;18&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;136&quot; data-start=&quot;18&quot;&gt;&lt;b&gt;23&lt;/b&gt;: 0x23 주소의 디바이스가 응답했다는 의미입니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;136&quot; data-start=&quot;62&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;136&quot; data-start=&quot;62&quot;&gt;i2cdetect가 &amp;ldquo;ping&amp;rdquo; 방식으로 해당 주소에 읽기 시도를 해서 ACK(응답)를 받으면 16진수 주소를 표시합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;343&quot; data-start=&quot;138&quot;&gt;&lt;b&gt;UU&lt;/b&gt;: 그 주소(예: 0x23)에 이미 커널 드라이버가 바인딩(bind)되어 있어서, 유저 공간에서 직접 probing(읽기/쓰기)하지 않는다는 뜻입니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;343&quot; data-start=&quot;237&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;343&quot; data-start=&quot;237&quot;&gt;이미 /sys/bus/i2c/devices/&amp;hellip;/driver 아래에 해당 디바이스가 등록되어 있으면, 안전을 위해 i2cdetect는 &amp;ldquo;사용 중(Used)&amp;rdquo; 표시로 바꿔버립니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;348&quot; data-start=&quot;345&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;356&quot; data-start=&quot;350&quot; data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;460&quot; data-start=&quot;358&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;460&quot; data-start=&quot;384&quot;&gt;
&lt;tr data-end=&quot;416&quot; data-start=&quot;384&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;389&quot; data-start=&quot;384&quot;&gt;23&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;397&quot; data-start=&quot;389&quot;&gt;장치가 응답함&lt;/td&gt;
&lt;td data-end=&quot;416&quot; data-start=&quot;397&quot; data-col-size=&quot;sm&quot;&gt;아직 커널 드라이버 미등록 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;460&quot; data-start=&quot;417&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;422&quot; data-start=&quot;417&quot;&gt;UU&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;433&quot; data-start=&quot;422&quot;&gt;드라이버가 바인딩됨&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;460&quot; data-start=&quot;433&quot;&gt;드라이버에서 이미 사용 중이므로 스캔하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/524</guid>
      <comments>https://hotari.tistory.com/524#entry524comment</comments>
      <pubDate>Mon, 23 Jun 2025 16:57:52 +0900</pubDate>
    </item>
    <item>
      <title>8일차</title>
      <link>https://hotari.tistory.com/523</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.20&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdXQ3R/btsOKETTXnh/LxRP11zIAB1hFWUhOPd5H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdXQ3R/btsOKETTXnh/LxRP11zIAB1hFWUhOPd5H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdXQ3R/btsOKETTXnh/LxRP11zIAB1hFWUhOPd5H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdXQ3R%2FbtsOKETTXnh%2FLxRP11zIAB1hFWUhOPd5H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;422&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #e7f3f8;&quot; data-token-index=&quot;0&quot;&gt;리눅스 디바이스 드라이버&lt;/span&gt; &amp;rArr; 임베디드에서 관심 영역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;역할
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디바이스 드라이버는 하드웨어를 사용 가능하게 만들어 줄 뿐 하드웨어를 어떻게 사용 할지에 대한 결정은 응용 프로그램에게 넘겨야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;고려사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최대한 유연하고 많은 기능을 사용자에게 제공하려고 할 수록 디바이스 드라이버 제작자는 많은 부분을 구현 해야한다.&lt;/li&gt;
&lt;li&gt;동기식, 비동기식 모두 지원할 것인가?&lt;/li&gt;
&lt;li&gt;장치를 여러 번 열 것 인가?&lt;/li&gt;
&lt;li&gt;정책 독립성을 제공할 것인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제공되는 디바이스 드라이버 유틸리티
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디바이스 제어와 구성을 도울 목적으로 간단한 유틸리티와 디바이스 드라이버를 같이 출시하는 경우가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모놀리식 방식
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기 리눅스 커널은 모놀로딕 방식으로 커널에 모든 디바이스 드라이버를 포함 시켜야 했다.&lt;/li&gt;
&lt;li&gt;이런 방식은 디바이스가 바뀔때마다 커널 컴파일을 다시 해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모듈구동 방식
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커널이 동작중인 상태에서 디바이스 드라이버를 동적으로 추가하거나 제거할 수 있는 개념으로 개발 시간을 효과적으로 단축할 수 있다.&lt;/li&gt;
&lt;li&gt;PCI, USB, PCMCIA에 관련된 디바이스의 PNP기능을 지원하려면 모듈 방식이 필요하다.&lt;/li&gt;
&lt;li&gt;모듈 방식은 MMU가 있는 프로세서에서만 지원되며, 커널 버전이 동일해야 하는 문제가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hello_module.c&lt;/p&gt;
&lt;pre id=&quot;code_1750382774244&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/init.h&amp;gt;

MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Your Name&quot;);
MODULE_DESCRIPTION(&quot;Simple Hello World module&quot;);

static int __init hello_init(void) {
    printk(KERN_INFO &quot;Hello World from kernel module!\n&quot;);
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO &quot;Goodbye from kernel module!\n&quot;);
}

module_init(hello_init);
module_exit(hello_exit);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Makefile&lt;/p&gt;
&lt;pre id=&quot;code_1750382786875&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj-m := hello_module.o
KDIR := $(HOME)/project/linux
PWD  := $(shell pwd)

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;make&amp;nbsp;-j12&amp;nbsp;ARCH=arm64&amp;nbsp;CROSS_COMPILE=aarch64-linux-gnu-&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IEzEz/btsOHZMJAVR/uQwgjNG7NiHujKqzCqEXs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IEzEz/btsOHZMJAVR/uQwgjNG7NiHujKqzCqEXs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IEzEz/btsOHZMJAVR/uQwgjNG7NiHujKqzCqEXs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIEzEz%2FbtsOHZMJAVR%2FuQwgjNG7NiHujKqzCqEXs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1051&quot; height=&quot;192&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blB2WR/btsOH0ESr36/qYhq3mQirtsEsy2b1VHmMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blB2WR/btsOH0ESr36/qYhq3mQirtsEsy2b1VHmMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blB2WR/btsOH0ESr36/qYhq3mQirtsEsy2b1VHmMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblB2WR%2FbtsOH0ESr36%2FqYhq3mQirtsEsy2b1VHmMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;639&quot; height=&quot;400&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;64&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oZw8o/btsOKR6Li9Z/4y4SBkKiDz8huKyBS0zimK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oZw8o/btsOKR6Li9Z/4y4SBkKiDz8huKyBS0zimK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oZw8o/btsOKR6Li9Z/4y4SBkKiDz8huKyBS0zimK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoZw8o%2FbtsOKR6Li9Z%2F4y4SBkKiDz8huKyBS0zimK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1016&quot; height=&quot;64&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;64&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5NDLW/btsOKTKhoTV/UAfzCOcKslEYTLin9I9XNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5NDLW/btsOKTKhoTV/UAfzCOcKslEYTLin9I9XNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5NDLW/btsOKTKhoTV/UAfzCOcKslEYTLin9I9XNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5NDLW%2FbtsOKTKhoTV%2FUAfzCOcKslEYTLin9I9XNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;365&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nfDXm/btsOKqn4LrE/QIqHTNPXspRwRYAo5HHKC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nfDXm/btsOKqn4LrE/QIqHTNPXspRwRYAo5HHKC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nfDXm/btsOKqn4LrE/QIqHTNPXspRwRYAo5HHKC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnfDXm%2FbtsOKqn4LrE%2FQIqHTNPXspRwRYAo5HHKC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;183&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUOobg/btsOJxnYQYr/eBVhKIxjKhovH6cYmRpUMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUOobg/btsOJxnYQYr/eBVhKIxjKhovH6cYmRpUMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUOobg/btsOJxnYQYr/eBVhKIxjKhovH6cYmRpUMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUOobg%2FbtsOJxnYQYr%2FeBVhKIxjKhovH6cYmRpUMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;218&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhfALI/btsOJMSG7wG/GUqkLQh2RDjof0cSvj6yfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhfALI/btsOJMSG7wG/GUqkLQh2RDjof0cSvj6yfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhfALI/btsOJMSG7wG/GUqkLQh2RDjof0cSvj6yfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhfALI%2FbtsOJMSG7wG%2FGUqkLQh2RDjof0cSvj6yfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;206&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;문자 디바이스 드라이버 예제 (하드웨어 불필요)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;char_dev.c&lt;/p&gt;
&lt;pre id=&quot;code_1750385941235&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;

#define DEV_NAME &quot;mychardev&quot;
static int major_num;

static ssize_t dev_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
{
    const char *msg = &quot;Hello from kernel!\n&quot;;
    return simple_read_from_buffer(buf, len, offset, msg, strlen(msg));
}

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .read = dev_read,
};

static int __init char_dev_init(void)
{
    major_num = register_chrdev(0, DEV_NAME, &amp;amp;fops);
    if (major_num &amp;lt; 0) {
        pr_err(&quot;Device registration failed\n&quot;);
        return major_num;
    }
    pr_info(&quot;Major number: %d\n&quot;, major_num);
    return 0;
}

static void __exit char_dev_exit(void)
{
    unregister_chrdev(major_num, DEV_NAME);
    pr_info(&quot;char_dev removed\n&quot;);
}

module_init(char_dev_init);
module_exit(char_dev_exit);

MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0iKh2/btsOKUh9yiS/Zp276OOHbF9BiosP2r0PHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0iKh2/btsOKUh9yiS/Zp276OOHbF9BiosP2r0PHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0iKh2/btsOKUh9yiS/Zp276OOHbF9BiosP2r0PHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0iKh2%2FbtsOKUh9yiS%2FZp276OOHbF9BiosP2r0PHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1015&quot; height=&quot;457&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bluEG0/btsOJOXeTLO/tZhbZw46aJm1Q275qREeA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bluEG0/btsOJOXeTLO/tZhbZw46aJm1Q275qREeA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bluEG0/btsOJOXeTLO/tZhbZw46aJm1Q275qREeA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbluEG0%2FbtsOJOXeTLO%2FtZhbZw46aJm1Q275qREeA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;743&quot; height=&quot;442&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RNZ0l/btsOKtE846L/I2DsHFelRTPFkrYLklAXV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RNZ0l/btsOKtE846L/I2DsHFelRTPFkrYLklAXV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RNZ0l/btsOKtE846L/I2DsHFelRTPFkrYLklAXV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRNZ0l%2FbtsOKtE846L%2FI2DsHFelRTPFkrYLklAXV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;801&quot; height=&quot;136&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJqspu/btsOKBpBwLq/IlekzpKkxA0yX05GDXPM9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJqspu/btsOKBpBwLq/IlekzpKkxA0yX05GDXPM9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJqspu/btsOKBpBwLq/IlekzpKkxA0yX05GDXPM9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJqspu%2FbtsOKBpBwLq%2FIlekzpKkxA0yX05GDXPM9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;806&quot; height=&quot;80&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cY5LcQ/btsOIyHXy2v/hL6FBsnNrHUWJ8I6jsHSS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cY5LcQ/btsOIyHXy2v/hL6FBsnNrHUWJ8I6jsHSS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cY5LcQ/btsOIyHXy2v/hL6FBsnNrHUWJ8I6jsHSS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcY5LcQ%2FbtsOIyHXy2v%2FhL6FBsnNrHUWJ8I6jsHSS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;385&quot; height=&quot;56&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;leddrv.c&lt;/p&gt;
&lt;pre id=&quot;code_1750637128677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;
#include &amp;lt;linux/uaccess.h&amp;gt;
#include &amp;lt;linux/io.h&amp;gt;

#define DEV_NAME &quot;led-driver&quot;
#define BCM_BASE 0xFE000000
#define GPIO_BASE (BCM_BASE + 0x200000)

#define GPIO_PIN 18

static void __iomem *gpio_base;
#define INP_GPIO(g)   (*(volatile unsigned int *)(gpio_base + ((g)/10)*4) &amp;amp;= ~(7 &amp;lt;&amp;lt; (((g)%10)*3)))
#define OUT_GPIO(g)   (*(volatile unsigned int *)(gpio_base + ((g)/10)*4) |=  (1 &amp;lt;&amp;lt; (((g)%10)*3)))
#define GPIO_SET(g)   (*(volatile unsigned int *)(gpio_base + 0x1C) = (1 &amp;lt;&amp;lt; g))
#define GPIO_CLR(g)   (*(volatile unsigned int *)(gpio_base + 0x28) = (1 &amp;lt;&amp;lt; g))

static int major;

static ssize_t myled_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
    char kbuf[2] = {0};

    if (copy_from_user(kbuf, buf, 1)) return -EFAULT;

    if (kbuf[0] == '1') {
           GPIO_SET(GPIO_PIN);  // 켜기
           pr_info(&quot;LED ON\n&quot;);
        }
    else if (kbuf[0] == '0') {
         GPIO_CLR(GPIO_PIN);  // 끄기
        pr_info(&quot;LED OFF\n&quot;);
}

    return count;
}

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .write = myled_write,
};

static int __init myled_init(void)
{
    major = register_chrdev(0, DEV_NAME, &amp;amp;fops);
    if (major &amp;lt; 0) return major;

    gpio_base = ioremap(GPIO_BASE, 0x100);
    INP_GPIO(GPIO_PIN);
    OUT_GPIO(GPIO_PIN);

    pr_info(&quot;myled loaded: /dev/%s (major %d)\n&quot;, DEV_NAME, major);
    return 0;
}

static void __exit myled_exit(void)
{
    unregister_chrdev(major, DEV_NAME);
    if (gpio_base) iounmap(gpio_base);
    pr_info(&quot;myled unloaded\n&quot;);
}

module_init(myled_init);
module_exit(myled_exit);
MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myled.c&lt;/p&gt;
&lt;pre id=&quot;code_1750637142506&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int main(int argc, char *argv[])
{
    int fd;
    if (argc != 2 || (argv[1][0] != '0' &amp;amp;&amp;amp; argv[1][0] != '1')) {
        printf(&quot;사용법: %s 0|1\n&quot;, argv[0]);
        return 1;
    }

    fd = open(&quot;/dev/led-driver&quot;, O_WRONLY);
    if (fd &amp;lt; 0) {
        perror(&quot;디바이스 열기 실패&quot;);
        return 1;
    }

    write(fd, argv[1], 1);
    close(fd);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1Pp1l/btsOLwwoB2Y/Wm90IooGg1aykE0OOTslkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1Pp1l/btsOLwwoB2Y/Wm90IooGg1aykE0OOTslkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1Pp1l/btsOLwwoB2Y/Wm90IooGg1aykE0OOTslkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1Pp1l%2FbtsOLwwoB2Y%2FWm90IooGg1aykE0OOTslkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;524&quot; height=&quot;289&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo&amp;nbsp;mknod&amp;nbsp;/dev/led-driver&amp;nbsp;c&amp;nbsp;$(grep&amp;nbsp;led-driver&amp;nbsp;/proc/devices&amp;nbsp;|&amp;nbsp;awk&amp;nbsp;'{print&amp;nbsp;$1}')&amp;nbsp;0&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQFIAy/btsOK9Ig8yH/hbUa0MHK1kfi6Ys97RKt2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQFIAy/btsOK9Ig8yH/hbUa0MHK1kfi6Ys97RKt2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQFIAy/btsOK9Ig8yH/hbUa0MHK1kfi6Ys97RKt2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQFIAy%2FbtsOK9Ig8yH%2FhbUa0MHK1kfi6Ys97RKt2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;865&quot; height=&quot;233&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYS8us/btsOMQ1GjJ6/06cuszjAgb1wFXoyp71oEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYS8us/btsOMQ1GjJ6/06cuszjAgb1wFXoyp71oEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYS8us/btsOMQ1GjJ6/06cuszjAgb1wFXoyp71oEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYS8us%2FbtsOMQ1GjJ6%2F06cuszjAgb1wFXoyp71oEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;43&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/523</guid>
      <comments>https://hotari.tistory.com/523#entry523comment</comments>
      <pubDate>Mon, 23 Jun 2025 09:10:03 +0900</pubDate>
    </item>
    <item>
      <title>7일차</title>
      <link>https://hotari.tistory.com/521</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.19&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;개발 환경 구축&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 사용하는 컴파일러는 GCC를 주로 사용하며 디버거로 는 GDB를 사용하고 있다. 타깃 보드가 ARM 계열 프로세서를 사용하고 있으면 ARM용 GCC 컴파일러를 설치하고, 타깃 보드가 x86 계열 프로세서를 사용하고 있으면 x86용 GCC 컴파일러를 설치하여 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브이엠웨어(VMWare), 버추얼 박스(VirtualBox), Xen 하이버 바이저&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdRW8X/btsOIo6CEYv/cjRL2K5EScsKJOJo3sxv70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdRW8X/btsOIo6CEYv/cjRL2K5EScsKJOJo3sxv70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdRW8X/btsOIo6CEYv/cjRL2K5EScsKJOJo3sxv70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdRW8X%2FbtsOIo6CEYv%2FcjRL2K5EScsKJOJo3sxv70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;468&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;크로스 개발환경 구축&lt;/b&gt;&lt;/h1&gt;
&lt;h1&gt;개발 시스템 구축&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Download Linux ISO Image - 로그인 필요 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ubuntu.com/download/desktop&quot;&gt;https://ubuntu.com/download/desktop&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Window + VM + Linux 개발 시스템 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VM - memory 4GB이상, HD 30GB 이상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Download VMPlayer&amp;nbsp; - 로그인 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion&quot;&gt;https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VMWare Tools 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치중 사용자 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크로스 툴 체인 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt update&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt upgrade -y&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt install git&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt install crossbuild-essential-arm64 &amp;lt;= 64bit&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt install crossbuild-essential-armhf &amp;lt;= 32bit&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;RaspberryPi 커널 컴파일&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.raspberrypi.com/documentation/computers/linux_kernel.html&quot;&gt;https://www.raspberrypi.com/documentation/computers/linux_kernel.html&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1750380066863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd project/
git clone --depth=1 --branch rpi-6.12.y  https://github.com/raspberrypi/linux

sudo apt install bc bison flex libssl-dev make libc6-dev libncurses5-dev

sudo apt install crossbuild-essential-arm64

cd linux
# .bashrc에 등록
vim .bashrc
KERNEL=kernel8  
#확인
echo $KERNEL

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

#
vim .config
CONFIG_LOCALVERSION=&quot;-v8-MY_CUSTOM_KERNEL&quot;

make -j12 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

#sudo env PATH=$PATH make -j12 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/home/ubuntu/rpi_modules modules_install
#scp -r /home/andrew/rpi_modules/lib/modules/6.12.33-v8-MY_CUSTOM_KERNEL+ pi@192.168.55.40:/lib/modules/

# rpi에 /home/kernel폴더 생성 -&amp;gt; 밑에 modules, root, boot폴더 생성
#오래 걸림 =&amp;gt; tar로 압축해서 복사하는거는?
#scp -r /home/andrew/rpi_modules/lib/modules/6.12.33-v8-MY_CUSTOM_KERNEL+ pi@192.168.55.40:/home/kernel/modules/
sudo make -j12 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/home/ubuntu/kernel/modules modules_install

sudo tar cf rpi_modules.tar rpi_module/
scp -r /home/andrew/rpi_modules.tar pi@192.168.55.40:/home/pi/kernel/modules/


#sudo cp mnt/boot/$KERNEL.img mnt/boot/$KERNEL-backup.img
#sudo cp arch/arm64/boot/Image mnt/boot/$KERNEL.img
#sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/boot/
#sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/boot/overlays/
#sudo cp arch/arm64/boot/dts/overlays/README mnt/boot/overlays/

#linux 폴더에서 


scp -r /home/ubuntu/project/linux/arch/arm64/boot/Image pi@10.10.16.221:/home/pi/kernel/boot/$KERNEL.img
scp -r /home/ubuntu/project/linux/arch/arm64/boot/dts/broadcom/*.dtb pi@10.10.16.221:/home/pi/kernel/boot/
scp -r /home/ubuntu/project/linux/arch/arm64/boot/dts/overlays/*.dtb* pi@10.10.16.221:/home/pi/kernel/boot/overlays/
scp -r /home/ubuntu/project/linux/arch/arm64/boot/dts/overlays/README pi@10.10.16.221:/home/pi/kernel/boot/overlays/


#라즈베리파이 /home/pi/kernel/modules에서
sudo mv 6.12.33-v8-MY_CUSTOM_KERNEL+/ /lib/modules/

#라즈베리파이 
sudo cp /home/pi/kernel/boot/kernel8.img /boot/firmware/6.12.33-v8-MY_CUSTOM_KERNEL+.img

sudo cp /home/pi/kernel/boot/* /boot/
sudo cp /home/pi/kernel/boot/overlays/* /boot/overlays

# 라즈베리파이 에서 부팅시 이미지 참조위치 변경
#config.txt =&amp;gt; /boot/firmware  in the boot partition to select your kernel:
sudo vim /boot/firmware/config.txt

[all]
kernel=6.12.33-v8-MY_CUSTOM_KERNEL+.img

sudo reboot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/521</guid>
      <comments>https://hotari.tistory.com/521#entry521comment</comments>
      <pubDate>Fri, 20 Jun 2025 09:41:30 +0900</pubDate>
    </item>
    <item>
      <title>6일차</title>
      <link>https://hotari.tistory.com/520</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.18&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.thread_create.c&lt;/p&gt;
&lt;pre id=&quot;code_1750207750475&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;

void *thread_function(void *arg);

int main() {
	int status;
	pthread_t tid;
	pthread_attr_t attr;
	void *thread_result;
	int i;
	

	pthread_attr_init(&amp;amp;attr);
	status = pthread_create(&amp;amp;tid, &amp;amp;attr, thread_function, &quot;hello thread&quot;);
	// status = pthread_create(&amp;amp;tid, NULL, thread_function,(void *) NULL);
	if(status !=0){
		perror(&quot;pthread_create&quot;);
		exit(1);
	}
	printf(&quot;Created Thread ID = %u\n&quot;, (unsigned int)tid);
	
	for(i=1; i&amp;lt;=5; i++){
		printf(&quot;Parent thread %d!!\n&quot;, i);
		sleep(1);
	}
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t tpid, pid;
	
	pthread_t thread_id;
	thread_id = pthread_self();
	printf(&quot;Thread ID: %u\n&quot;, (unsigned int)thread_id);

	for(i=1; i&amp;lt;=10; i++){
		printf(&quot;\t\tChild thread[%d] - %s\n&quot;, i, (char *)arg);
		sleep(1);
	}
	return NULL;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rPiK3/btsOEjR2wxh/gnGxXOcSWVOBuebVkTI491/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rPiK3/btsOEjR2wxh/gnGxXOcSWVOBuebVkTI491/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rPiK3/btsOEjR2wxh/gnGxXOcSWVOBuebVkTI491/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrPiK3%2FbtsOEjR2wxh%2FgnGxXOcSWVOBuebVkTI491%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;301&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.thread_join.c&lt;/p&gt;
&lt;pre id=&quot;code_1750209661535&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

//#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;

void *thread_function(void *arg);

int main() {
	int status;
	pthread_t tid;
	void *return_value;
	int i;

	
	status = pthread_create(&amp;amp;tid, NULL, thread_function, &quot;hello thread\n&quot;);
	if(status !=0){
		perror(&quot;pthread_create&quot;);
		exit(1);
	}
	
	for(i=1; i&amp;lt;=5; i++){
		printf(&quot;Parent thread %d!!\n&quot;, i);
		sleep(1);
	}

	//
	status = pthread_join(tid, &amp;amp;return_value);
	if(status != 0){
		perror(&quot;pthread_join&quot;);
		exit(1);
	}
	printf(&quot;Thread joined, it returned %s\n&quot;, (char *)return_value); 
	// printf(&quot;Thread joined, it returned %ld\n&quot;, (uintptr_t)return_value); 
	
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t * tpid;
	pthread_t * thread_id;
	
	tpid=malloc(sizeof(pid_t));
	thread_id=malloc(sizeof(pthread_t));

	*tpid = syscall(SYS_gettid);
	printf(&quot;Thread LWP: %d, Thread PID: %d\n&quot;, *tpid, getpid());
	
	*thread_id = pthread_self();
	printf(&quot;Thread ID: %lu\n&quot;, *thread_id);
	
	for(i=1; i&amp;lt;=10; i++){
		printf(&quot;\t\tChild thread %d\n&quot;, i);
		sleep(1);
	}
	// pthread_exit(&quot;Good Bye&quot;);
	// return (void *)1;
	pthread_exit((void *)0);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1Yyxk/btsOEODZHTa/ZH6MfK1qYe31HZUkpWDUMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1Yyxk/btsOEODZHTa/ZH6MfK1qYe31HZUkpWDUMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1Yyxk/btsOEODZHTa/ZH6MfK1qYe31HZUkpWDUMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Yyxk%2FbtsOEODZHTa%2FZH6MfK1qYe31HZUkpWDUMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;385&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.thread_exit.c&lt;/p&gt;
&lt;pre id=&quot;code_1750210399050&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

//#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;

void *thread_function(void *arg);

int main() {
	int status, i;
	pthread_t tid;
	void *thread_result;
	void * ret;

	status = pthread_create(&amp;amp;tid, NULL, thread_function, &quot;hello thread&quot;);
	if(status !=0){
		perror(&quot;pthread_create&quot;);
		exit(1);
	}
	
	sleep(1);
	pthread_cancel(tid);
	pthread_join(tid, &amp;amp;ret);
	printf(&quot;RET = %ld\n&quot;, (intptr_t)ret);
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t tpid, pid;
	int ret, unused;
#if 0
	ret = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &amp;amp;unused);
#else
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
#endif

	for(int i=1; i&amp;lt;=10; i++){
		printf(&quot;\tChild thread %d\n&quot;, i);
		for(int k=0; k&amp;lt;300000000; k++) {}
		if(i==7){
			pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &amp;amp;unused);
		}
	}
	return (void *) 5;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HzH6l/btsOEiezHIZ/TFQP4aUwlkx2AqSnEgHnWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HzH6l/btsOEiezHIZ/TFQP4aUwlkx2AqSnEgHnWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HzH6l/btsOEiezHIZ/TFQP4aUwlkx2AqSnEgHnWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHzH6l%2FbtsOEiezHIZ%2FTFQP4aUwlkx2AqSnEgHnWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;148&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.multi-thread.c&lt;/p&gt;
&lt;pre id=&quot;code_1750211063486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

void *isprime(void *arg);
void *progress(void *arg);

int main(int argc, char *argv[]){
  long long num1;
  long long num2;
  pthread_t tid1, tid2, tid3;
  pthread_attr_t attr;
  if (argc != 3) {
    fprintf(stderr, &quot;Please supply two numbers.\n&quot; &quot;Example: %s 9 7\n&quot;, argv[0]);
    return 1;
  }
  num1 = atoll(argv[1]);
  num2 = atoll(argv[2]);
  
  pthread_attr_init(&amp;amp;attr);
  
  pthread_create(&amp;amp;tid3, &amp;amp;attr, progress, NULL);
  pthread_detach(tid3);
  
  pthread_create(&amp;amp;tid1, &amp;amp;attr, isprime, &amp;amp;num1);
  pthread_create(&amp;amp;tid2, &amp;amp;attr, isprime, &amp;amp;num2);
  
  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  
  pthread_attr_destroy(&amp;amp;attr);
  if (pthread_cancel(tid3) != 0)
     fprintf(stderr, &quot;Couldn't cancel progress thread\n&quot;);
  printf(&quot;Done!\n&quot;);
	sleep(3);
  return 0;
}

void *isprime(void *arg){
   long long int number = *((long long*)arg);
   long long int j;
   int prime = 1;
    
   for(j=2; j&amp;lt;number; j++) {
      if(number%j == 0){
         prime = 0;
      }
   }
   if(prime == 1){
      printf(&quot;\n%lld is a prime number\n&quot;, number);
      return NULL;
   }else{
      printf(&quot;\n%lld is not a prime number\n&quot;, number);
      return NULL;
   }
}

void *progress(void *arg){
   while(1) {
      sleep(1);
      printf(&quot;.&quot;);
      fflush(stdout);
   }
   return NULL;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf72U0/btsOFLztrrD/oQ6TM4onjCtIPYwccXkUP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf72U0/btsOFLztrrD/oQ6TM4onjCtIPYwccXkUP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf72U0/btsOFLztrrD/oQ6TM4onjCtIPYwccXkUP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf72U0%2FbtsOFLztrrD%2FoQ6TM4onjCtIPYwccXkUP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;141&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.thread-return.c&lt;/p&gt;
&lt;pre id=&quot;code_1750211116159&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

void *isprime(void *arg);
void *progress(void *arg);

int main(int argc, char *argv[]){
   long long num1;
   long long num2;
   pthread_t tid1;
   pthread_t tid2;
   pthread_t tid3;
   void *result1;
   void *result2;
   if (argc != 3){
      fprintf(stderr, &quot;Please supply two numbers.\n&quot; &quot;Example: %s 9 7\n&quot;, argv[0]);
      return 1;
   }
   num1 = atoll(argv[1]);
   num2 = atoll(argv[2]);
   
   pthread_create(&amp;amp;tid3, NULL, progress, NULL);  
   pthread_detach(tid3);
   pthread_create(&amp;amp;tid1, NULL, isprime, &amp;amp;num1);
   pthread_create(&amp;amp;tid2, NULL, isprime, &amp;amp;num2);

   pthread_join(tid1, &amp;amp;result1);
   if ((uintptr_t)result1 == 1)
      printf(&quot;\n%lld is a prime number\n&quot;, num1);
   else
      printf(&quot;\n%lld is not a prime number\n&quot;, num1);
         
   pthread_join(tid2, &amp;amp;result2);   
   if ((uintptr_t)result2 == 1)
      printf(&quot;\n%lld is a prime number\n&quot;, num2);
   else
      printf(&quot;\n%lld is not a prime number\n&quot;, num2);
   
   if ( pthread_cancel(tid3) != 0 )
      fprintf(stderr, &quot;Couldn't cancel progress thread\n&quot;);
   return 0;
}

void *isprime(void *arg) {
   long long int number = *((long long*)arg);
   long long int j;
   int prime = 1;
    
   for(j=2; j&amp;lt;number; j++){
      if(number%j == 0)
         prime = 0;
   }
   if(prime == 1)
      return (void*)1;
   else
      return (void*)0;
}

void *progress(void *arg){
   while(1){
      sleep(1);
      printf(&quot;.&quot;);
      fflush(stdout);
   }
   return NULL;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZOYOy/btsOFmfXwm8/HvAkUWKMBmkuornGwYWQw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZOYOy/btsOFmfXwm8/HvAkUWKMBmkuornGwYWQw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZOYOy/btsOFmfXwm8/HvAkUWKMBmkuornGwYWQw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZOYOy%2FbtsOFmfXwm8%2FHvAkUWKMBmkuornGwYWQw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;234&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.endian_conv.c&lt;/p&gt;
&lt;pre id=&quot;code_1750213915576&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main(int argc, char *argv[]){
	unsigned char *addr;
	unsigned int host_addr;
	unsigned int net_addr;
	
	struct sockaddr_in sock_addr;

	host_addr=0xc0a83865;
	printf(&quot;LIEELE ENDIAN = %#x\n&quot;, host_addr);
	addr = (unsigned char *)&amp;amp;host_addr;
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	
	sock_addr.sin_addr.s_addr=host_addr;
	printf(&quot;LITTLE ENDIAN IP_ADDR = %s\n\n&quot;, inet_ntoa(sock_addr.sin_addr));
	
	net_addr=htonl(host_addr);
	printf(&quot;BIG ENDIAN = %#x\n&quot;, net_addr);
	addr = (unsigned char *)&amp;amp;net_addr;
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	printf(&quot;MEM-ADDR = %p \t\t%#x\n&quot;, addr, *addr++);
	
	sock_addr.sin_addr.s_addr=net_addr;	
	printf(&quot;BIG ENDIAN IP_ADDR = %s\n&quot;, inet_ntoa(sock_addr.sin_addr));
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUfe5/btsOF9AaYgH/KcyFmmykU6VK78P8UspFgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUfe5/btsOF9AaYgH/KcyFmmykU6VK78P8UspFgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUfe5/btsOF9AaYgH/KcyFmmykU6VK78P8UspFgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUfe5%2FbtsOF9AaYgH%2FKcyFmmykU6VK78P8UspFgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;299&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.ip-address.c&lt;/p&gt;
&lt;pre id=&quot;code_1750217039741&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main(int argc, char * argv[]){
	in_addr_t ipaddr;
	struct sockaddr_in sock_addr; 
	struct in_addr sip_addr;
	unsigned char *addr;
	
	ipaddr=inet_network(argv[1]); 	// host_addr=inet_network(&quot;192.168.60.100&quot;);
	printf(&quot;inet_network() = %#x\n&quot;, ipaddr);
	addr = (unsigned char *)&amp;amp;ipaddr;
	printf(&quot;MEM-ADDR = %p &quot;, addr);
	printf(&quot; --&amp;gt; %#x &quot;, *addr);
	printf(&quot;\t%#x %#x %#x %#x\n&quot;, *addr, *addr++, *addr++, *addr++);
	
	sock_addr.sin_addr.s_addr=inet_addr(argv[1]);
	ipaddr=sock_addr.sin_addr.s_addr;
	printf(&quot;inet_addr() = %#x\n&quot;, ipaddr);
	addr = (unsigned char *)&amp;amp;ipaddr;
	printf(&quot;MEM-ADDR = %p &quot;, addr);
	printf(&quot; --&amp;gt; %#x &quot;, *addr);
	printf(&quot;\t%#x %#x %#x %#x\n&quot;, *addr, *addr++, *addr++, *addr++);
	
	inet_aton(argv[1], &amp;amp;sip_addr);
	printf(&quot;inet_aton() = %#x\n&quot;, sip_addr.s_addr);
	ipaddr=sip_addr.s_addr;
	addr = (unsigned char *)&amp;amp;ipaddr;
	printf(&quot;MEM-ADDR = %p &quot;, addr);
	printf(&quot; --&amp;gt; %#x &quot;, *addr);
	printf(&quot;\t%#x %#x %#x %#x\n&quot;, *addr, *addr++, *addr++, *addr++);
	
	
	inet_pton(AF_INET, argv[1], &amp;amp;(sock_addr.sin_addr));
	printf(&quot;inet_pton() = %#x \n&quot;, sock_addr.sin_addr.s_addr);
	
	addr=inet_ntoa(sock_addr.sin_addr);
	printf(&quot;inet_ntoa() = %s\n&quot;, addr);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JERHB/btsOEOKN3PG/CyAOYogKZEkCq25tF0N5Rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JERHB/btsOEOKN3PG/CyAOYogKZEkCq25tF0N5Rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JERHB/btsOEOKN3PG/CyAOYogKZEkCq25tF0N5Rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJERHB%2FbtsOEOKN3PG%2FCyAOYogKZEkCq25tF0N5Rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;178&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.tcp_client.c&lt;/p&gt;
&lt;pre id=&quot;code_1750218305229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;netdb.h&amp;gt;

int main(int argc, char* argv[]){
	int sockfd;
	struct sockaddr_in sockaddr;
	char message[500];
	int bytes_recv;
	socklen_t len;
	
	if(argc!=3){
		printf(&quot;Usage : %s &amp;lt;IP&amp;gt; &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1){
		perror(&quot;sockfdet() error!!&quot;);
		exit(1);
	}
	
	memset(&amp;amp;sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));
		
	if(connect(sockfd, (struct sockaddr*)&amp;amp;sockaddr, sizeof(sockaddr))==-1){
		perror(&quot;connect() error!!&quot;);
		exit(1);
	}

#if 1			//It is to see the peer information in terms of name and port #
	len = sizeof(sockaddr);
	getpeername(sockfd, (struct sockaddr*)&amp;amp;sockaddr, &amp;amp;len);
	printf(&quot;Peer IP address: %s\n&quot;, inet_ntoa(sockaddr.sin_addr));
	printf(&quot;Peer port      : %d\n&quot;, ntohs(sockaddr.sin_port));
#endif
	bzero(&amp;amp;message, sizeof(message));
	bytes_recv=recv(sockfd, message, sizeof(message), 0);
	//bytes_recv=read(sockfd, message, sizeof(message));
	if(bytes_recv==-1){
		perror(&quot;recv() error!!&quot;);
		exit(1);
	}
	printf(&quot;Message from server: %s (%d)\n&quot;, message, bytes_recv); 
	
	printf(&quot;Press Enter to close the socket!!!&quot;);
	getchar();

	close(sockfd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.tcp_server.c&lt;/p&gt;
&lt;pre id=&quot;code_1750218066947&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

int main(int argc, char *argv[]){
	int server_sfd;
	int client_sfd;

	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sock_size;
	
	int bytes_sent;
	char message[]=&quot;Welcome to Linux Network Programming!&quot;;
	int yes = 1;
	
	if(argc!=2){
		printf(&quot;Usage : %s &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1){
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}

#if 1
	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1){
		perror(&quot;setsockopt() error!!&quot;);
		exit(1);
	}
#endif
	
	memset(&amp;amp;server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &amp;amp;server_addr, sizeof(server_addr))==-1 ){
		perror(&quot;bind() error!!&quot;);
		exit(1);
	}
	
	if(listen(server_sfd, 10)==-1){
		perror(&quot;listen() error!!&quot;);
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&amp;amp;client_addr,&amp;amp;sock_size);
	printf(&quot;Connected to the client port --&amp;gt; %d\n&quot;, htons(client_addr.sin_port));
	if(client_sfd==-1){
		perror(&quot;accept() error!!&quot;);
		exit(1);
	}
	
	bytes_sent = send(client_sfd, message, strlen(message), 0);
	//bytes_sent=write(client_sfd, message, sizeof(message));
	printf(&quot;bytes_sent : %d\n&quot;, bytes_sent);

	printf(&quot;Press Enter to close the socket!!!&quot;);
	getchar();

	close(client_sfd);	
	close(server_sfd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIvCUd/btsOEVwzEmO/RJ7TXBclfkZHR092PIN1A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIvCUd/btsOEVwzEmO/RJ7TXBclfkZHR092PIN1A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIvCUd/btsOEVwzEmO/RJ7TXBclfkZHR092PIN1A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIvCUd%2FbtsOEVwzEmO%2FRJ7TXBclfkZHR092PIN1A1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;86&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSEwQW/btsOFGyAhTc/6AFOVrLpbTWWcQumQs0iUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSEwQW/btsOFGyAhTc/6AFOVrLpbTWWcQumQs0iUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSEwQW/btsOFGyAhTc/6AFOVrLpbTWWcQumQs0iUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSEwQW%2FbtsOFGyAhTc%2F6AFOVrLpbTWWcQumQs0iUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;802&quot; height=&quot;100&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01-1.tcp_client_close.c&lt;/p&gt;
&lt;pre id=&quot;code_1750223838491&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;netdb.h&amp;gt;

/*
	This example requites to work with 02-1.tcp_server_close.c to see if what happens
	when server close the socket while waiting for recv().
	To test it, server keeps hiting the &quot;Enter&quot; until the socket is closed
*/

int main(int argc, char* argv[]) {
	int sockfd;
	struct sockaddr_in sockaddr;
	char message[500];
	int bytes_recv;
	
	if(argc!=3) {
		printf(&quot;Usage : %s &amp;lt;IP&amp;gt; &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1) {
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}
	
	memset(&amp;amp;sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));
		
	if(connect(sockfd, (struct sockaddr*)&amp;amp;sockaddr, sizeof(sockaddr))==-1) {
		perror(&quot;connect() error!!&quot;);
		exit(1);
	}
	for(int i=0; i&amp;lt;5; i++) {
		bzero(&amp;amp;message, sizeof(message));
		bytes_recv=recv(sockfd, message, sizeof(message), 0);
	//bytes_recv=read(sockfd, message, sizeof(message));
		if(bytes_recv==-1)	{
			perror(&quot;recv() error!!&quot;);
			exit(1);
	}
	if(bytes_recv == 0){
		printf(&quot;socket is closed by the other end!!!\n&quot;);
		break;
	}
		printf(&quot;Message from server: %s \n&quot;, message); 
	}
	
	close(sockfd);
	return 0;
}

/*
* while waiting for new message using recv, client may be able to detect 
* the lost of connection when a server close the socket.
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-1.tcp_server_close.c&lt;/p&gt;
&lt;pre id=&quot;code_1750223864557&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

/*
	This example may work together with 01.tcp_client.c 
	and the client is waiting for server to close the socket fibytes_sent
*/

int main(int argc, char *argv[]) {
	int server_sfd;
	int client_sfd;

	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t client_addr_size;
	
	int bytes_sent;

	char message[]=&quot;Welcome to Linux Network Programming!&quot;;

	int yes = 1;
	
	if(argc!=2) {
		printf(&quot;Usage : %s &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1) {
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}

#if 1
	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1) {
		perror(&quot;setsockopt() error!!&quot;);
		exit(1);
	}
#endif
	
	memset(&amp;amp;server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &amp;amp;server_addr, sizeof(server_addr))==-1 )	{
		perror(&quot;bind() error!!&quot;);
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1)	{
		perror(&quot;listen() error!!&quot;);
		exit(1);
	}
	
	client_addr_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&amp;amp;client_addr,&amp;amp;client_addr_size);
	printf(&quot;Connected to the client port --&amp;gt; %d\n&quot;, htons(client_addr.sin_port));
	if(client_sfd==-1) {
		perror(&quot;accept() error!!&quot;);
		exit(1);
	}
	
	bytes_sent = send(client_sfd, message, strlen(message), 0);
	printf(&quot;bytes_sent : %d\n&quot;, bytes_sent);
	//write(client_sfd, message, sizeof(message));
	if(bytes_sent == -1){
		printf(&quot;Socket is closed by the other end!!!\n&quot;);
		close(client_sfd);	
		close(server_sfd);
	}
	
	printf(&quot;Enter to send...&quot;);
	getchar();
	
	bytes_sent = send(client_sfd, message, sizeof(message), 0);
	printf(&quot;bytes_sent1 : %d\n&quot;, bytes_sent);
	//write(client_sfd, message, sizeof(message));
	if(bytes_sent == 0){
		printf(&quot;Socket1 is closed by the other end!!!\n&quot;);
		close(client_sfd);	
		close(server_sfd);
	}

	printf(&quot;Enter to send...&quot;);
	getchar();

	bytes_sent = send(client_sfd, message, sizeof(message), 0);
	printf(&quot;bytes_sent2 : %d\n&quot;, bytes_sent);
	//send() doesn't return 0 when the socket is not available due to close
	if(bytes_sent == -1){
		printf(&quot;Socket2 is closed by the other end!!!\n&quot;);
		close(client_sfd);	
		close(server_sfd);
	}
	
#if 1
	printf(&quot;Enter to close the socket!!!&quot;);
	getchar();
#endif
	close(client_sfd);	
	close(server_sfd);
	
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-1.tcp_server_sigpipe.c&lt;/p&gt;
&lt;pre id=&quot;code_1750223883020&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;

/*
	This example is to demonstrate how to detect lost of the socket connection 
	by using signal SIGPIPE which will be sent to the application when send() is failed 
	when socket is closed by the client
*/

int server_sfd;
int client_sfd;

void handler(int signo) {
	int ret;
	int status;
	
	printf(&quot;Server detected the connection lost by receiving signal(%d)\n&quot;, signo);
	close(client_sfd);	
	close(server_sfd);	
	printf(&quot;Sockets closed -----\n&quot;);
	
}

int main(int argc, char *argv[]) {
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sock_size;

	char message[]=&quot;Welcome to Linux Network Programming!&quot;;

	int yes = 1;
	
	if(argc!=2) {
		printf(&quot;Usage : %s &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	signal(SIGPIPE, handler);
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1){
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1){
		perror(&quot;setsockopt() error!!&quot;);
		exit(1);
	}
	
	memset(&amp;amp;server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &amp;amp;server_addr, sizeof(server_addr))==-1 ) {
		perror(&quot;bind() error!!&quot;);
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1) {
		perror(&quot;listen() error!!&quot;);
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&amp;amp;client_addr,&amp;amp;sock_size);
	printf(&quot;Connected to the client port --&amp;gt; %d\n&quot;, htons(client_addr.sin_port));
	if(client_sfd==-1){
		perror(&quot;accept() error!!&quot;);
		exit(1);
	}
	
	for(int i=0; i&amp;lt;10; i++){
		send(client_sfd, message, sizeof(message), 0);
		//write(client_sfd, message, sizeof(message));
		sleep(1);
	}
	
	return 0;
}

/*
* When server is tring to send a packet and the connection is closed by client,
* the kernel may detect it and deliver a signal of SIGPIPE to the server process. 
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.hello_client.c&lt;/p&gt;
&lt;pre id=&quot;code_1750223903507&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

int main(int argc, char *argv[]){
	int sockfd;
	struct sockaddr_in sockaddr;
	socklen_t sock_size;
	int bytes_sent;

	char message1[]=&quot;Hello world &quot;;
	char message2[]=&quot;Good morning &quot;;
	char message3[]=&quot;I am a few good man&quot;;

	if(argc!=3) {
		printf(&quot;Usage : %s &amp;lt;IP&amp;gt; &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1) {
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}

	memset(&amp;amp;sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));

	if(connect(sockfd, (struct sockaddr*)&amp;amp;sockaddr, sizeof(sockaddr))==-1) {
		perror(&quot;connect() error!!&quot;);
		exit(1);
	}
	
	bytes_sent = send(sockfd, message1, strlen(message1), 0);
	printf(&quot;bytes_sent1 = %d\n&quot;, bytes_sent);
	bytes_sent = send(sockfd, message2, strlen(message2), 0);
	printf(&quot;bytes_sent2 = %d\n&quot;, bytes_sent);
	bytes_sent = send(sockfd, message3, strlen(message3), 0);
	printf(&quot;bytes_sent3 = %d\n&quot;, bytes_sent);

	close(sockfd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.hello_server.c&lt;/p&gt;
&lt;pre id=&quot;code_1750223917307&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

int main(int argc, char* argv[]){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr, client_addr;
	socklen_t sock_size;
	char message[128];					//should be big enough to place the entire tcp_rx_buf
	int bytes_recv=0, idx=0;
	char t_rxbuf[20];					//should be enough to place the receive() size
	int yes = 1;
	
	if(argc!=2){
		printf(&quot;Usage : %s &amp;lt;port&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1)	{
		perror(&quot;socket() error!!&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1){
		perror(&quot;setsockopt() error!!&quot;);
		exit(1);
	}

	memset(&amp;amp;server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));
	
	if(bind(server_sfd, (struct sockaddr*) &amp;amp;server_addr, sizeof(server_addr))==-1 ) { 
		perror(&quot;bind() error!!&quot;);
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1) {
		perror(&quot;listen() error!!&quot;);
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&amp;amp;client_addr,&amp;amp;sock_size);
	if(client_sfd==-1) {
		perror(&quot;accept() error!!&quot;);
		exit(1);
	}

	bzero(&amp;amp;message, sizeof(message));
#if 0
	bytes_recv=recv(client_sfd, message, sizeof(message), 0);
#else
	while( bytes_recv=recv(client_sfd, &amp;amp;message[idx], 8, 0) ) {
		printf(&quot;Receiving index %d(%d)\n&quot;, idx, bytes_recv);
		if(bytes_recv == 0) {
			break;
		} else {
			memset(t_rxbuf, 0, sizeof(t_rxbuf));
			strncpy(t_rxbuf, &amp;amp;message[idx], bytes_recv);			
			printf(&quot;recv ok(%d:%s)\n&quot;, idx, t_rxbuf);
			idx += bytes_recv;
		}
		bytes_recv += bytes_recv;
	}
#endif
	
	printf(&quot;Message from %s: %s\n&quot;, inet_ntoa(client_addr.sin_addr), message);  
	close(client_sfd);
	close(server_sfd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.mytcpclient.c&lt;/p&gt;
&lt;pre id=&quot;code_1750224073100&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

int main(int argc, char *argv[]){
	int sockfd, bytes_recv; 
	struct sockaddr_in sockaddr;
	char tx_buf[128], rx_buf[128];
	int i;

	if(argc != 2){
		fprintf(stderr, &quot;usage : client serverip \n&quot;);
		exit(1);
	}

	//socket open
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		perror(&quot;socket() error&quot;);
		exit(1);
	}

	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(10000);
	sockaddr.sin_addr.s_addr = inet_addr(argv[1]);    
	/*  sockaddr.sin_addr.s_addr = inet_addr(&quot;70.12.117.90&quot;);  */
	memset(&amp;amp;(sockaddr.sin_zero), '\0',8);

	printf(&quot;[ %s ]\n&quot;, inet_ntoa(sockaddr.sin_addr));

	//connection request to server
	if(connect(sockfd, (struct sockaddr *)&amp;amp;sockaddr, sizeof(struct sockaddr)) == -1){
		perror(&quot;connect() error&quot;);
		exit(1);
	}
	
	for(i=1; i&amp;lt;=10; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		sprintf(tx_buf, &quot;Hello_%d server(from %d)!!\n&quot;, i, getpid());
		//messge send to server
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) 
			perror(&quot;send&quot;);
		//message rx wait from server
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror(&quot;recv&quot;);
			exit(1);
		}
		printf(&quot;-----&amp;gt;Client Received : %s&quot;, rx_buf);
		sleep((getpid()+i)%5);
	}
	//close socket
	close(sockfd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.mytcpserver_fork_wrong.c&lt;/p&gt;
&lt;pre id=&quot;code_1750224101140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;   
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;   
#include &amp;lt;sys/wait.h&amp;gt;

int main(void) {
	int server_sfd, client_sfd, bytes_recv;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	char tx_buf[128], rx_buf[128];
	int i;

	if((server_sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror(&quot;socket() error&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1) {
		perror(&quot;setsockopt() error&quot;);
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&amp;amp;(server_addr.sin_zero), '\0', 8);

	//server ip &amp;amp; port number setting
	if(bind(server_sfd, (struct sockaddr *)&amp;amp;server_addr, sizeof(struct sockaddr)) == -1) {
		perror(&quot;bind() error&quot;);
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1) {
		perror(&quot;listen() error&quot;);
		exit(1);
	}

	while(1) {
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *)&amp;amp;client_addr, &amp;amp;sock_size)) == -1) {
			perror(&quot;accept() error&quot;);
			continue;
		}

		printf(&quot;server : got connection from %s \n&quot;, inet_ntoa(client_addr.sin_addr));

		if(!fork()){
			close(server_sfd);
			for(i=1; ; i++) {
				memset(tx_buf, 0, sizeof(tx_buf));
				memset(rx_buf, 0, sizeof(rx_buf));
				//wait for rx data from client	
				if((bytes_recv = recv(client_sfd, rx_buf, sizeof(rx_buf), 0)) == -1){
					perror(&quot;recv&quot;);
					exit(1);
				}
				if(bytes_recv == 0) 
					break;	
				printf(&quot;Server Rx(%d) : %s&quot;, getpid(), rx_buf);
				sprintf(tx_buf, &quot;Hi_%d, client(from %s)~~\n&quot;, i, inet_ntoa(server_addr.sin_addr));
				//send data to client
				if(send(client_sfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror(&quot;send&quot;);	
			}
			printf(&quot;Server(%d): Client Connection Socket Closed!!\n&quot;, getpid());
			//close client socket connection		
			close(client_sfd);
			exit(0);
		}
		close(client_sfd);	//parent close the client socket as they are being servered by child
		waitpid(-1, NULL, WNOHANG);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tw2XX/btsOE5TL1Qr/oJ6wm9PosRsKvkjKI9zZt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tw2XX/btsOE5TL1Qr/oJ6wm9PosRsKvkjKI9zZt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tw2XX/btsOE5TL1Qr/oJ6wm9PosRsKvkjKI9zZt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftw2XX%2FbtsOE5TL1Qr%2FoJ6wm9PosRsKvkjKI9zZt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;272&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y3a36/btsOFOjkj4K/zVpTvQjJXXnA5ymLpgmRaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y3a36/btsOFOjkj4K/zVpTvQjJXXnA5ymLpgmRaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y3a36/btsOFOjkj4K/zVpTvQjJXXnA5ymLpgmRaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY3a36%2FbtsOFOjkj4K%2FzVpTvQjJXXnA5ymLpgmRaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;234&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-1.mytcpserver_fork_well.c&lt;/p&gt;
&lt;pre id=&quot;code_1750224522861&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;   
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;   
#include &amp;lt;sys/wait.h&amp;gt;

/* 
	Original example code has Zombie process left behind.
	In order to get rid of those Zombie process, it is mandatory, in this example, 
	to hand signal SIGCHLD which would be received when a child process is dead.
*/

void handler(int signo) {
	int ret;
	int status;
	
	printf(&quot;Signal Handler starts -----\n&quot;);
	ret = waitpid(-1, &amp;amp;status, WNOHANG);
	if(ret == 0) {
		printf(&quot;PID %d child process is dead\n&quot;, ret);
		// break;
	}
	if(ret == -1 &amp;amp;&amp;amp; errno == ECHILD) {
		printf(&quot;No Child --\n&quot;);
		// break;
	}
	if(ret == -1) {
		perror(&quot;child waitpid&quot;);
		abort();
	}
	printf(&quot;PID %d child process is dead\n&quot;, ret);
	printf(&quot;Signal Handler ends -----\n&quot;);
}

int main(void) {
	int server_sfd, client_sfd, bytes_recv;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	char tx_buf[128], rx_buf[128];
	int i;
	
	signal(SIGCHLD, handler);

	if((server_sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror(&quot;socket() error&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1) {
		perror(&quot;setsockopt() error&quot;);
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&amp;amp;(server_addr.sin_zero), '\0', 8);

	//server ip &amp;amp; port number setting
	if(bind(server_sfd, (struct sockaddr *)&amp;amp;server_addr, sizeof(struct sockaddr)) == -1) {
		perror(&quot;bind() error&quot;);
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1) {
		perror(&quot;listen() error&quot;);
		exit(1);
	}

	while(1) {
		
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *)&amp;amp;client_addr, &amp;amp;sock_size)) == -1) {
			perror(&quot;accept() error&quot;);
			continue;
		}

		printf(&quot;server : got connection from %s \n&quot;, inet_ntoa(client_addr.sin_addr));

		if(!fork())	{
			close(server_sfd);
			for(i=1; ; i++){
				memset(tx_buf, 0, sizeof(tx_buf));
				memset(rx_buf, 0, sizeof(rx_buf));
				//wait for rx data from client	
				if((bytes_recv = recv(client_sfd, rx_buf, sizeof(rx_buf), 0)) == -1) {
					perror(&quot;recv&quot;);
					exit(1);
				}
				if(bytes_recv == 0) 
					break;	
				printf(&quot;Server Rx(%d) : %s&quot;, getpid(), rx_buf);
				sprintf(tx_buf, &quot;Hi_%d, client(from %s)~~\n&quot;, i, inet_ntoa(server_addr.sin_addr));
				//send data to client
				if(send(client_sfd, tx_buf, strlen(tx_buf)+1, 0) == -1) 
					perror(&quot;send&quot;);	
			}
			printf(&quot;Server(%d): Client Connection Socket Closed!!\n&quot;, getpid());
			//close client socket connection		
			close(client_sfd);
			exit(0);
		}
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnwKwP/btsOGOCYe5U/A8g2Fka24IvpAAmC4IT461/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnwKwP/btsOGOCYe5U/A8g2Fka24IvpAAmC4IT461/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnwKwP/btsOGOCYe5U/A8g2Fka24IvpAAmC4IT461/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnwKwP%2FbtsOGOCYe5U%2FA8g2Fka24IvpAAmC4IT461%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;319&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRSe3m/btsOFm8NABA/wGiW03vYkPxqQdOGICITT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRSe3m/btsOFm8NABA/wGiW03vYkPxqQdOGICITT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRSe3m/btsOFm8NABA/wGiW03vYkPxqQdOGICITT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRSe3m%2FbtsOFm8NABA%2FwGiW03vYkPxqQdOGICITT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;237&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-2.mytcpserver_nonblock.c&lt;/p&gt;
&lt;pre id=&quot;code_1750224570077&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;   
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;   
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

void * server_function (void * args) {
	int bytes_recv;
	int sockfd = *((int*)args);
	char tx_buf[128], rx_buf[128];
	
	for(int i=1; ; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror(&quot;recv&quot;);
			exit(1);
		}
		if(bytes_recv == 0) break;	
		printf(&quot;Server Rx(%d) : %s&quot;, getpid(), rx_buf);
		sprintf(tx_buf, &quot;Hi_%d, client(from %d)~~\n&quot;, i, getpid());
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror(&quot;send&quot;);	
	}
	printf(&quot;Server(%d): Client Connection Socket Closed!!\n&quot;, getpid());
	close(sockfd);
	return NULL;
}

int main(void){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	int i;
	pthread_t tid;

	if((server_sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		perror(&quot;socket() error&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1){
		perror(&quot;setsockopt() error&quot;);
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&amp;amp;(server_addr.sin_zero), '\0', 8);

	//server ip &amp;amp; port number setting
	if(bind(server_sfd, (struct sockaddr *)&amp;amp;server_addr, sizeof(struct sockaddr)) == -1){
		perror(&quot;bind() error&quot;);
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1){
		perror(&quot;listen() error&quot;);
		exit(1);
	}

	while(1){
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *) &amp;amp;client_addr, &amp;amp;sock_size)) == -1){
			perror(&quot;accept() error&quot;);
			continue;
		}

		printf(&quot;server : got connection from %s \n&quot;, inet_ntoa(client_addr.sin_addr));
		pthread_create(&amp;amp;tid, NULL, server_function, &amp;amp;client_sfd);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpcRpf/btsOFXOjr8v/w5Yk6P4xEywVmjKk279QHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpcRpf/btsOFXOjr8v/w5Yk6P4xEywVmjKk279QHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpcRpf/btsOFXOjr8v/w5Yk6P4xEywVmjKk279QHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpcRpf%2FbtsOFXOjr8v%2Fw5Yk6P4xEywVmjKk279QHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;269&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzHSlz/btsOFIcnL4s/YUJPAF4xbY2R7wek7UIDzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzHSlz/btsOFIcnL4s/YUJPAF4xbY2R7wek7UIDzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzHSlz/btsOFIcnL4s/YUJPAF4xbY2R7wek7UIDzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzHSlz%2FbtsOFIcnL4s%2FYUJPAF4xbY2R7wek7UIDzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;233&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-2.mytcpserver_thread.c&lt;/p&gt;
&lt;pre id=&quot;code_1750228432044&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;   
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;   
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

void * server_function (void * args) {
	int bytes_recv;
	int sockfd = *((int*)args);
	char tx_buf[128], rx_buf[128];
	
	for(int i=1; ; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror(&quot;recv&quot;);
			exit(1);
		}
		if(bytes_recv == 0) break;	
		printf(&quot;Server Rx(%d) : %s&quot;, getpid(), rx_buf);
		sprintf(tx_buf, &quot;Hi_%d, client(from %d)~~\n&quot;, i, getpid());
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror(&quot;send&quot;);	
	}
	printf(&quot;Server(%d): Client Connection Socket Closed!!\n&quot;, getpid());
	close(sockfd);
	return NULL;
}

int main(void){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	int i;
	pthread_t tid;

	if((server_sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		perror(&quot;socket() error&quot;);
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(int)) == -1){
		perror(&quot;setsockopt() error&quot;);
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&amp;amp;(server_addr.sin_zero), '\0', 8);

	//server ip &amp;amp; port number setting
	if(bind(server_sfd, (struct sockaddr *)&amp;amp;server_addr, sizeof(struct sockaddr)) == -1){
		perror(&quot;bind() error&quot;);
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1){
		perror(&quot;listen() error&quot;);
		exit(1);
	}

	while(1){
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *) &amp;amp;client_addr, &amp;amp;sock_size)) == -1){
			perror(&quot;accept() error&quot;);
			continue;
		}

		printf(&quot;server : got connection from %s \n&quot;, inet_ntoa(client_addr.sin_addr));
		pthread_create(&amp;amp;tid, NULL, server_function, &amp;amp;client_sfd);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ydKYe/btsOF31Rser/xhNyZtOTW2SkWRVcdvTuuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ydKYe/btsOF31Rser/xhNyZtOTW2SkWRVcdvTuuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ydKYe/btsOF31Rser/xhNyZtOTW2SkWRVcdvTuuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FydKYe%2FbtsOF31Rser%2FxhNyZtOTW2SkWRVcdvTuuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;258&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dczfiy/btsOGZxDBjF/skLMAC5xtUpzI7LxgV0fs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dczfiy/btsOGZxDBjF/skLMAC5xtUpzI7LxgV0fs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dczfiy/btsOGZxDBjF/skLMAC5xtUpzI7LxgV0fs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdczfiy%2FbtsOGZxDBjF%2FskLMAC5xtUpzI7LxgV0fs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;233&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/520</guid>
      <comments>https://hotari.tistory.com/520#entry520comment</comments>
      <pubDate>Wed, 18 Jun 2025 16:19:54 +0900</pubDate>
    </item>
    <item>
      <title>5일차</title>
      <link>https://hotari.tistory.com/519</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.17&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;07.myexecl.c&lt;/p&gt;
&lt;pre id=&quot;code_1750121077453&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;wait.h&amp;gt;

int main(void) {
	pid_t pid;
	int status;
	switch (pid=fork()) {
		case -1:
			perror(&quot;fork failed&quot;);
			break;
		case 0:				// child process
			printf(&quot;CHILD PROCESS : %d\n&quot;, getpid());
			if(execl(&quot;./01.mytask&quot;, &quot;01.mytask&quot;, &quot;10&quot;, (char *) 0) == -1)
				perror(&quot;execl&quot;);
		default:
			sleep(1);
			system(&quot;ps -lf&quot;);
			pid = wait(&amp;amp;status);
			printf(&quot;parent : waited (%d) and completed!\n&quot;, pid);
			exit(0);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nD4bn/btsODLmhepn/iEQ2icAnSDRPGSsKfhEKO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nD4bn/btsODLmhepn/iEQ2icAnSDRPGSsKfhEKO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nD4bn/btsODLmhepn/iEQ2icAnSDRPGSsKfhEKO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnD4bn%2FbtsODLmhepn%2FiEQ2icAnSDRPGSsKfhEKO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;918&quot; height=&quot;503&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;07-1.myexecl.c&lt;/p&gt;
&lt;pre id=&quot;code_1750121378765&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;wait.h&amp;gt;

void handler(int signo) {
	pid_t exit_pid;
	printf(&quot;\nhandler_pid [%d], handler_ppid [%d]\n&quot;, getpid(), getppid());
	exit_pid = waitpid(-1, NULL, WNOHANG);
	if(exit_pid == -1)
		perror(&quot;waitpid&quot;);
	else
		printf(&quot;Terminated child PID = %d\n&quot;, exit_pid);
}

int main(void) {
	pid_t pid;
	
	signal(SIGCHLD, handler);
	switch (pid=fork()) {
		case 0:				// child process
			printf(&quot;CHILD PROCESS : %d\n&quot;, getpid());
			char *args[] = {&quot;01.mytask&quot;, &quot;10&quot;, NULL};
			if(execv(&quot;./01.mytask&quot;, args) == -1)
				perror(&quot;execv&quot;);
			exit(100);
		default:
			getchar();
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byT83z/btsOCf9IOVL/RzmJU57TD1zTMPuxfXcVk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byT83z/btsOCf9IOVL/RzmJU57TD1zTMPuxfXcVk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byT83z/btsOCf9IOVL/RzmJU57TD1zTMPuxfXcVk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyT83z%2FbtsOCf9IOVL%2FRzmJU57TD1zTMPuxfXcVk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;838&quot; height=&quot;157&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;157&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;08.mydaemon.c&lt;/p&gt;
&lt;pre id=&quot;code_1750122867399&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;syslog.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;syslog.h&amp;gt;

int main(void) {
	pid_t pid, sid;
	int fd, fd0, fd1, fd2;
	time_t now;
	
	if((pid = fork()) != 0) {
		exit(0);																							//parent exit
	}
	sid=setsid();
	umask(0022); 			
	chdir(&quot;/&quot;);
	close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO);
	fd = open(&quot;/tmp/mydaemon.log&quot;, O_WRONLY | O_CREAT | O_TRUNC, 0666);
	dup2(fd, 1); dup2(fd, 2);
	while(1){
		time(&amp;amp;now);
		fprintf(stdout, &quot;Mydaemon alive at %s&quot;, ctime(&amp;amp;now));
		fflush(stdout); 																			/* flush the stream */
		sleep(5);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6GP9w/btsOEiqpPAW/8KEFM2ZmcmVcRSjU5khPB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6GP9w/btsOEiqpPAW/8KEFM2ZmcmVcRSjU5khPB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6GP9w/btsOEiqpPAW/8KEFM2ZmcmVcRSjU5khPB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6GP9w%2FbtsOEiqpPAW%2F8KEFM2ZmcmVcRSjU5khPB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;883&quot; height=&quot;155&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/snWvn/btsOECCbPNk/5e1QJ5sPb5hYdx6rFayyg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/snWvn/btsOECCbPNk/5e1QJ5sPb5hYdx6rFayyg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/snWvn/btsOECCbPNk/5e1QJ5sPb5hYdx6rFayyg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsnWvn%2FbtsOECCbPNk%2F5e1QJ5sPb5hYdx6rFayyg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;591&quot; height=&quot;274&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;09.mydaemon.service&lt;/p&gt;
&lt;pre id=&quot;code_1750125037804&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Unit]
Description=Mydaemon testing via by systemd
[Service]
ExecStart=/usr/local/bin/09.mydaemon-systemd
Restart=on-failure
Type=forking
PIDFile=/run/mydaemon.pid
[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;09.mydaemon-systemd.c&lt;/p&gt;
&lt;pre id=&quot;code_1750125022665&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;syslog.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;

void sigHandler(int sig);

int fd;
const char pidfile[] = &quot;/run/mydaemon.pid&quot;;
const char daemonlog[]=&quot;/tmp/mydaemon.log&quot;;

int main(int argc, char * argv[]) {
	pid_t pid, sid;
	time_t now;
	struct sigaction action;
		
	if((pid = fork()) != 0) { 
		exit(0);									//parent exit and child continues
	}
	
	if((pid = fork()) !=0 ) {		//double forking
		exit(0);					
	}
	
	sid=setsid();
	if ((fd = open(pidfile, O_RDWR | O_CREAT)) == -1){
			perror(&quot;Can't open file for writing&quot;);
			return 1;
	}
	dprintf(fd, &quot;%d\n&quot;, getpid());
	
	umask(0); 			
	if(chdir(&quot;/&quot;) !=0 ) {
		perror(&quot;chdir&quot;);
		exit(1);
	}
	
	close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO);
	
	/* prepare for sigaction */
	action.sa_handler = sigHandler;
	sigfillset(&amp;amp;action.sa_mask);
	action.sa_flags = SA_RESTART;
	/* register the signals we want to handle */
	sigaction(SIGTERM, &amp;amp;action, NULL);
	sigaction(SIGINT, &amp;amp;action, NULL);
	sigaction(SIGQUIT, &amp;amp;action, NULL);
	sigaction(SIGABRT, &amp;amp;action, NULL);
	
	if((access(daemonlog, F_OK)) == 0){
	   unlink(daemonlog);
   }
	
	if ((fd = open(daemonlog, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1){
		perror(&quot;Can't open daemonlog&quot;);
		return 1;
	}
	while(1){
		time(&amp;amp;now);
		dprintf(fd, &quot;Mydaemon alive at %s&quot;, ctime(&amp;amp;now));
		sleep(5);
	}
	return 0;
}

void sigHandler(int sig){
    int status = 0;
    if ( sig == SIGTERM || sig == SIGINT || sig == SIGQUIT || sig == SIGABRT ){
        if ((unlink(pidfile)) == -1)			/* remove the pid-file */
            status = 1;
        if ((close(fd)) == -1)
            status = 1;
		if ((unlink(daemonlog)) == -1)			/* remove the daemonlog */
            status = 1;
        exit(status); 							/* exit with the status set*/
    }else{										/* some other signal */
        exit(1);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;207&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqnwaR/btsOEMEL4Nn/EDoDfzxa0LOrOJeKASC3EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqnwaR/btsOEMEL4Nn/EDoDfzxa0LOrOJeKASC3EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqnwaR/btsOEMEL4Nn/EDoDfzxa0LOrOJeKASC3EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqnwaR%2FbtsOEMEL4Nn%2FEDoDfzxa0LOrOJeKASC3EK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;706&quot; height=&quot;207&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;207&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8QWpD/btsOCjqIEDH/UyfI8NbywqVYlaH7bikFZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8QWpD/btsOCjqIEDH/UyfI8NbywqVYlaH7bikFZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8QWpD/btsOCjqIEDH/UyfI8NbywqVYlaH7bikFZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8QWpD%2FbtsOCjqIEDH%2FUyfI8NbywqVYlaH7bikFZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;394&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.mypipe1.c&lt;/p&gt;
&lt;pre id=&quot;code_1750127133024&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main(void) {
	int pd[2], read_fd, write_fd;
	pid_t pid;
	time_t timer1, timer2;
	char tx_buf[100], rx_buf[100];
	
	if ( pipe(pd) == -1 ) {
		perror(&quot;pipe&quot;);    
		exit(1);    
	}
	
	read_fd = pd[0];    
	write_fd = pd[1];
  
	switch(pid=fork()) {
		case 0: 
			close(read_fd);
			for(int i=0; i&amp;lt;11; i++){
				// for(timer1=time(NULL); time(NULL)&amp;lt;timer1 + 1;)
				// continue;
				// strcpy(tx_buf, &quot;\e[31mHello Parent. I am child.&quot;);
				sprintf(tx_buf, &quot;\e[31mHello Parent. I am child ---%d\n&quot;, i);
				write(write_fd, tx_buf, strlen(tx_buf)+1);
				for(timer1=time(NULL); time(NULL)&amp;lt;timer1 + 1;)
				continue;
				// read(read_fd, rx_buf, sizeof(rx_buf));
				// printf(&quot;\e[00m--------&amp;gt; CHILD: %s\n&quot;, rx_buf);
			}
			exit(0);
		default:   
#if 1
			close(write_fd);
			for(int i=0; i&amp;lt;10; i++){
				// for(timer2=time(NULL); time(NULL)&amp;lt;timer2 + 2;)
					// continue;
				// memset(&amp;amp;rx_buf[0], 0, sizeof(rx_buf));
				read(read_fd, rx_buf, sizeof(rx_buf));
				printf(&quot;\e[00mPARENT: %s\n&quot;, rx_buf);
				// for(timer2=time(NULL); time(NULL)&amp;lt;timer2 + 2;)
					// continue;
				// strcpy(tx_buf, &quot;\e[00mHello Child. I am Parent&quot;);
				// sprintf(tx_buf, &quot;\e[00mWeleome Child. I am Parent--%d\n&quot;, i);
				// write(write_fd, tx_buf, strlen(tx_buf)+1);
			}
#else
			for(int i=0; i&amp;lt;10; i++){
				for(timer2=time(NULL); time(NULL)&amp;lt;timer2 + 2;)
					continue;
				strcpy(tx_buf, &quot;\e[00mHello Child. I am Parent&quot;);
				write(write_fd, tx_buf, strlen(tx_buf)+1);
				read(read_fd, rx_buf, sizeof(rx_buf));
				printf(&quot;\e[00mPARENT: %s\n&quot;, rx_buf);
			}
#endif
			exit(0);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biM6UP/btsOEQAphg3/gPVRNcKdsS8frFTD8BFCQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biM6UP/btsOEQAphg3/gPVRNcKdsS8frFTD8BFCQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biM6UP/btsOEQAphg3/gPVRNcKdsS8frFTD8BFCQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiM6UP%2FbtsOEQAphg3%2FgPVRNcKdsS8frFTD8BFCQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;436&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.mypipe2.c&lt;/p&gt;
&lt;pre id=&quot;code_1750127272886&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

#define MSGSIZE	64

int main(void){
	int pd1[2], pd2[3];
	pid_t ret;
	time_t timer1;
	char sbuf[MSGSIZE];
	char rbuf[MSGSIZE];
	int i, len;
	
	if(pipe(pd1) == -1){
		perror(&quot;pipe1&quot;);
		exit(1);
	}
	
	if(pipe(pd2) == -1){
		perror(&quot;pipe2&quot;);
		exit(1);
	}
	
	
	switch(fork()){
		case 0:					//child
			close(pd1[0]);
			close(pd2[1]);
			for(i=0; i&amp;lt;5; i++) {
				sprintf(&amp;amp;sbuf[0], &quot;Hello, Parent #%d&quot;, i+1);
				write(pd1[1], sbuf, strlen(sbuf));
				
				memset(&amp;amp;rbuf[0], 0, MSGSIZE);
				len = read(pd2[0], rbuf, MSGSIZE);
				if(len == 0){
					break;
				}
				printf(&quot;CHILD: %s\n&quot;, rbuf);
				for(timer1=time(NULL); time(NULL)&amp;lt;timer1 + 1;)
					continue;
			}
			exit(0);
		default:				//parent
			close(pd1[1]);
			close(pd2[0]);
			for(i=0; ; i++) {
				memset(&amp;amp;rbuf[0], 0, MSGSIZE);
				len = read(pd1[0], rbuf, MSGSIZE);
				if(len == 0){
					break;
				}
				printf(&quot;PARENT: %s\n&quot;, rbuf);
				for(timer1=time(NULL); time(NULL)&amp;lt;timer1 + 1;)
					continue;
				sprintf(&amp;amp;sbuf[0], &quot;Welcome, Child #%d&quot;, i+1);
				write(pd2[1], sbuf, strlen(sbuf));
			}
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekLttW/btsODUDD0lB/UZUtEVXdo9WlUHGCaaLDuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekLttW/btsODUDD0lB/UZUtEVXdo9WlUHGCaaLDuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekLttW/btsODUDD0lB/UZUtEVXdo9WlUHGCaaLDuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekLttW%2FbtsODUDD0lB%2FUZUtEVXdo9WlUHGCaaLDuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;244&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.myfifo_recv.c&lt;/p&gt;
&lt;pre id=&quot;code_1750127425307&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(){
	int fd;
	char buf[128];
	int count = 0;
	
	if((access (&quot;/tmp/myfifo&quot;, F_OK)) != 0){
		if(mkfifo(&quot;/tmp/myfifo&quot;, S_IRUSR | S_IWUSR) == -1){
			perror(&quot;mkfifo&quot;);
			exit(1);
		}
	}
	
	if((fd = open(&quot;/tmp/myfifo&quot;, O_RDONLY)) == -1){
		perror(&quot;open&quot;);
		exit(1);
	}
	
	while(1){
		memset(buf, 0, sizeof(buf));
		read(fd, buf, sizeof(buf));
		printf(&quot;Rx - %s\n&quot;, buf);
		if(strstr(buf, &quot;end&quot;)){
			break;
		}
	}
	close(fd);
	unlink(&quot;/tmp/myfifo&quot;);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.myfifo_send.c&lt;/p&gt;
&lt;pre id=&quot;code_1750127689931&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main(){
	int fd, i;
	char buf[128];
	time_t timer1;
	
	if((fd = open(&quot;/tmp/myfifo&quot;, O_WRONLY)) == -1){
		perror(&quot;open&quot;);
		exit(2);
	}
	
	for(i=0; i&amp;lt;5; i++){
		memset(buf, 0, sizeof(buf));
		sprintf(&amp;amp;buf[0], &quot;Hello(%d)&quot;, i);
		write(fd, &amp;amp;buf[0], strlen(buf)+1);
		printf(&quot;Tx: %s\n&quot;, buf);
		for(timer1=time(NULL); time(NULL)&amp;lt;timer1 + 2;)
			continue;
	}
	memset(buf, 0, sizeof(buf));
	sprintf(buf, &quot;end&quot;);
	write(fd, buf, strlen(buf)+1);
	close(fd);
	/* unlink(&quot;/tmp/mkfifo&quot;); */
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXgWnY/btsOE46gSPA/1A4B8ae1u4i2ngTcfd2751/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXgWnY/btsOE46gSPA/1A4B8ae1u4i2ngTcfd2751/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXgWnY/btsOE46gSPA/1A4B8ae1u4i2ngTcfd2751/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXgWnY%2FbtsOE46gSPA%2F1A4B8ae1u4i2ngTcfd2751%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;124&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dE60at/btsODJhMa6q/34VPNHLIPCpGsVWKj2kiF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dE60at/btsODJhMa6q/34VPNHLIPCpGsVWKj2kiF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dE60at/btsODJhMa6q/34VPNHLIPCpGsVWKj2kiF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdE60at%2FbtsODJhMa6q%2F34VPNHLIPCpGsVWKj2kiF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;143&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.posix_shm_write.c&lt;/p&gt;
&lt;pre id=&quot;code_1750144170629&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;  
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;       
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#define  MEM_SIZE    128

int main() {
	int fd;
	void *shm_addr;
	const char *message0= &quot;Welcome to &quot;;
	const char *message1= &quot;Linux Systems &quot;;
	const char *message2= &quot;Programming!&quot;;
	
	
	fd = shm_open(&quot;/mydata&quot;, O_RDWR | O_CREAT, 0666);
	
	
	ftruncate(fd, MEM_SIZE);
		
	
	shm_addr = mmap(0, MEM_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
	printf( &quot;Map addr is %p\n&quot;, shm_addr );
#if 1	
	write(fd, message0, strlen(message0));
	write(fd, message1, strlen(message1));
	write(fd, message2, strlen(message2));
#else
	memcpy(shm_addr, message0, strlen(message0));
	shm_addr += strlen(message0);
	sprintf(shm_addr, message1, strlen(message1));
	shm_addr += strlen(message1);
	memcpy(shm_addr, message2, strlen(message2));
	shm_addr += strlen(message2);
#endif
	printf(&quot;Press enter to munmap.... &quot;);
	getchar();
	munmap(shm_addr, MEM_SIZE);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.posix_shm_read.c&lt;/p&gt;
&lt;pre id=&quot;code_1750144207440&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;  
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#define  MEM_SIZE    128

int main() {
	int fd;
	void *shm_addr;
	char buf[MEM_SIZE];

	fd = shm_open(&quot;/mydata&quot;, O_RDONLY, 0666);
	if(fd == -1){
		perror(&quot;shm_open&quot;);
		exit(1);
	}
	
	
	shm_addr = mmap(0, MEM_SIZE, PROT_READ, MAP_SHARED, fd, 0);
	if(shm_addr == (void *)-1){
		perror(&quot;mmap error&quot;);
		return EXIT_FAILURE;
	}
#if 1	
	memset(buf, 0, MEM_SIZE);
	read(fd, buf, MEM_SIZE);
	printf(&quot;%s\n&quot;, buf);
#else
	memcpy(buf, shm_addr, sizeof(buf));
	printf(&quot;Map addr is %p\n&quot;, shm_addr);
	printf(&quot;Read message: %s\n&quot;, buf);
#endif
	printf(&quot;Press enter to munmap .....&quot;);
	getchar();
	munmap(shm_addr, MEM_SIZE);
	printf(&quot;Press enter to remove shared memory file&quot;);
	getchar();
	shm_unlink(&quot;/mydata&quot;);
	// close(fd);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.posix-mqsend.c&lt;/p&gt;
&lt;pre id=&quot;code_1750144224510&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;mqueue.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#define MAX_MSG_SIZE 2048

int main(int argc, char *argv[]){
	int mqd; /* msg queue descriptor */
	/* attributes for the message queue */
	struct mq_attr msgattr;
	msgattr.mq_maxmsg = 10;
	msgattr.mq_msgsize = MAX_MSG_SIZE;
	char msg[128];

	mqd = mq_open(&quot;/myqueue&quot;, O_CREAT|O_RDWR, 0644, &amp;amp;msgattr); 
	if(mqd == -1){
	  perror(&quot;Creating message queue&quot;);
	  return 1;
	}
	for(int i=0; i&amp;lt;10; i++){
		sprintf(&amp;amp;msg[0], &quot;Hello, message queue #%d&quot;, i+1);
		if((mq_send(mqd, msg, strlen(msg), 1)) == -1){
			perror(&quot;Message queue send&quot;);
			return 1;
		}
	}
	printf(&quot;Press Enter to remove message queue....&quot;);
	getchar();
	
	mq_close(mqd);
	mq_unlink(&quot;/myqueue&quot;);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.posix-mqrecv.c&lt;/p&gt;
&lt;pre id=&quot;code_1750144240604&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;mqueue.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(void){
   int mqd; 								/* msg queue descriptor */
   char *buffer;
   struct mq_attr msgattr;
   mqd = mq_open(&quot;/myqueue&quot;, O_RDONLY);
   if(mqd == -1){
      perror(&quot;Open message queue&quot;);
      return 1;
   }
   if((mq_getattr(mqd, &amp;amp;msgattr)) == -1){
      perror(&quot;Get message attribute&quot;);
      return 1;
   }
   buffer = calloc(msgattr.mq_msgsize, sizeof(char));
   if(buffer == NULL){
      fprintf(stderr, &quot;Couldn't allocate memory&quot;);
      return 1;
   }
   printf(&quot;%ld messages in queue\n&quot;, msgattr.mq_curmsgs);
   for(int i = 0; i&amp;lt;msgattr.mq_curmsgs; i++){
      if((mq_receive(mqd, buffer, msgattr.mq_msgsize, NULL)) == -1){
         perror(&quot;Message receive&quot;);
         return 1;
      }
      printf(&quot;%s\n&quot;, buffer);
   }
   memset(buffer, '\0', msgattr.mq_msgsize);
   free(buffer);
   mq_close(mqd);
   //mq_unlink(&quot;/myqueue&quot;);
   return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.shm_posix_named_sem1.c&lt;/p&gt;
&lt;pre id=&quot;code_1750146062989&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;semaphore.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/shm.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;

#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;

#define KEY_NUM     0x2222
#define	MEM_SIZE		1024

int main(int argc, char **argv) {
  sem_t *mysem;
	int shm_id;
	void *shm_addr;

	printf(&quot;Started --------------------\n&quot;);
	if((shm_id = shmget((key_t)KEY_NUM,MEM_SIZE,IPC_CREAT|0666)) == -1) {
		perror(&quot;shmget&quot;);
		exit(1);
	}

	if((shm_addr = shmat(shm_id, NULL, 0)) == (void *)-1) {
		perror(&quot;shmat&quot;);
		exit(1);
	}
	
	printf(&quot;Named semaphore ---------------\n&quot;);
  if((mysem = sem_open(&quot;/mysemaphore&quot;, O_CREAT, 0777, 1)) == NULL) {
    perror(&quot;Sem Open Error&quot;);
    return 1;
  }

  for(int i=0; i&amp;lt;500; i++){
#ifdef SEM
    sem_wait(mysem);
#endif
		sprintf((char *)shm_addr, &quot;%d&quot;, getpid());
		for(int j=0; j&amp;lt;5000000; j++){}
		if(getpid() == atoi(shm_addr))
			putchar('0');
		else
			putchar('X');
		fflush(stdout);
#ifdef SEM
		sem_post(mysem);
#endif
    }
	if(shmdt(shm_addr) !=0){
		perror(&quot;shmdt&quot;);
		exit(2);
	}
	sem_close(mysem);
	sem_unlink(&quot;/mysemaphore&quot;);
	if(shmctl(shm_id, IPC_RMID, NULL) == -1){
		perror(&quot;shmctl&quot;);
		exit(2);
	}
}

// sem.mysem file for mysem semaphore is located in /dev/shm
// To compile the program, -lrt &amp;amp; -lpthread is required&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mV1rz/btsOFjiZJYu/Rrh6gqCwt4ZLt7LVmtQ4s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mV1rz/btsOFjiZJYu/Rrh6gqCwt4ZLt7LVmtQ4s1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mV1rz/btsOFjiZJYu/Rrh6gqCwt4ZLt7LVmtQ4s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmV1rz%2FbtsOFjiZJYu%2FRrh6gqCwt4ZLt7LVmtQ4s1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;144&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.shm_posix_named_sem2.c&lt;/p&gt;
&lt;pre id=&quot;code_1750146129992&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;semaphore.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/shm.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;

#include &amp;lt;stdlib.h&amp;gt; 
#include &amp;lt;stdio.h&amp;gt;

#define KEY_NUM     0x2222
#define	MEM_SIZE	1024
        
int main(int argc, char **argv){       
	sem_t *mysem;
	int shm_id;
	void *shm_addr;
	
	printf(&quot;Started --------------------\n&quot;);
	if((shm_id = shmget((key_t)KEY_NUM,MEM_SIZE,IPC_CREAT|0666)) == -1) {
		perror(&quot;shmget&quot;);
		exit(1);
	}

	if((shm_addr = shmat(shm_id, NULL, 0)) == (void *)-1) {
		perror(&quot;shmat&quot;);
		exit(1);
	}
	
	printf(&quot;Named semaphore ---------------\n&quot;);
	if((mysem = sem_open(&quot;/mysemaphore&quot;, O_CREAT, 0777, 1)) == SEM_FAILED) {
			perror(&quot;Sem Open Error&quot;);
			return 1;
	}

	for(int i=0; i&amp;lt;500; i++){  
#ifdef SEM	
		sem_wait(mysem);
#endif
		sprintf((char *)shm_addr, &quot;%d&quot;, getpid());
		for(int j=0; j&amp;lt;3000000; j++){}
		if(getpid() == atoi(shm_addr))
			putchar('0');
		else
			putchar('X');
		fflush(stdout);
#ifdef SEM
		sem_post(mysem);
#endif
                
	}  
	if(shmdt(shm_addr) !=0){
		perror(&quot;shmdt&quot;);
		exit(2);
	}
	sem_close(mysem);
	sem_unlink(&quot;/mysemaphore&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qNY2x/btsOFtTab2t/Ep5eWhkZlB1is8gpXZKwI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qNY2x/btsOFtTab2t/Ep5eWhkZlB1is8gpXZKwI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qNY2x/btsOFtTab2t/Ep5eWhkZlB1is8gpXZKwI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqNY2x%2FbtsOFtTab2t%2FEp5eWhkZlB1is8gpXZKwI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;818&quot; height=&quot;147&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/519</guid>
      <comments>https://hotari.tistory.com/519#entry519comment</comments>
      <pubDate>Tue, 17 Jun 2025 16:51:29 +0900</pubDate>
    </item>
    <item>
      <title>4일차</title>
      <link>https://hotari.tistory.com/518</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.16&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;00.process.c&lt;/p&gt;
&lt;pre id=&quot;code_1750033174164&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int a=10, a2=20;
int b, b2;

int f1(int x){
	return ++x;
}

int f2(int x){
	return --x;
}

int main(){
	int c=100, c2;
	char *d = &quot;\e[31mThis is virtual memory layout of the process\e[00m&quot;;
	// char *d; 
	char *name;
	
	name = malloc(40);
	name = &quot;cafe&quot;;
	
	printf(&quot;addr(TEXT)=&amp;gt; \tmain:%p, f1:%p, f2:%p\n&quot;, main, f1, f2);
	printf(&quot;addr(CONST)=&amp;gt; \td:%p : %s\n&quot;, *(&amp;amp;d), d);
	printf(&quot;addr(DATA)=&amp;gt; \ta:%p, a2:%p, a_value:%d, a2_value:%d\n&quot;, &amp;amp;a, &amp;amp;a2,*(&amp;amp;a), *(&amp;amp;a2));
	printf(&quot;addr(BSS)=&amp;gt; \tb:%p, b2:%p, b_value:%d, b2_value:%d\n&quot;, &amp;amp;b, &amp;amp;b2, *(&amp;amp;b), *(&amp;amp;b2));
	printf(&quot;addr(HEAP)=&amp;gt; \tname_var:%p, name_addr:%p, name:%s\n&quot;, &amp;amp;name, name, name );
	printf(&quot;addr(STACK)=&amp;gt; \tc:%p, c_value:%d\n&quot;, &amp;amp;c, *(&amp;amp;c));
	printf(&quot;addr(STACK)=&amp;gt; \td:%p, d_value:%p\n&quot;, &amp;amp;d, *(&amp;amp;d));
	// c=200; c2=300;
	// printf(&quot;addr(STACK)=&amp;gt; c:%p, c_value:%d, c2:%p, c2_value:%d\n&quot;, &amp;amp;c, *(&amp;amp;c), &amp;amp;c2, *(&amp;amp;c2));
	sleep(1);
	strcpy(d, &quot;hello world&quot;);
	printf(&quot;addr(CONST)=&amp;gt; \td:%p : %s\n&quot;, d, d);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3rhRg/btsOCKG8o2O/FRNf3Dh0arl1N4oJrurxQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3rhRg/btsOCKG8o2O/FRNf3Dh0arl1N4oJrurxQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3rhRg/btsOCKG8o2O/FRNf3Dh0arl1N4oJrurxQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3rhRg%2FbtsOCKG8o2O%2FFRNf3Dh0arl1N4oJrurxQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;704&quot; height=&quot;208&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cli_args.c&lt;/p&gt;
&lt;pre id=&quot;code_1750033736498&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;stdio.h&amp;gt;

int main(int argc, char * argv[]){
   
    printf(&quot;Number of Arguments Passed: %d\n&quot;, argc);
    // This loop prints the all the command line values that are passed through the program
    for(int i=0; i&amp;lt;argc; i++){
        printf(&quot;%s\n&quot;, argv[i]);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKdtVc/btsOA9uPlTY/fsT1hF2OC9jYKoJrRfgOoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKdtVc/btsOA9uPlTY/fsT1hF2OC9jYKoJrRfgOoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKdtVc/btsOA9uPlTY/fsT1hF2OC9jYKoJrRfgOoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKdtVc%2FbtsOA9uPlTY%2FfsT1hF2OC9jYKoJrRfgOoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;234&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;env_list.c&lt;/p&gt;
&lt;pre id=&quot;code_1750033999668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;stdio.h&amp;gt;

int main(){

    extern char **environ;

    char **environment_list = environ;

    /* This code Helps us to prints the all the Environments available 
	 * in the operating system.
    */
	
    while(*environment_list != NULL){
        printf(&quot;%s\n&quot;, *environment_list);
        environment_list++;
    }
	
	// for(int i=0; i&amp;lt;10; i++){
        // printf(&quot;%s\n&quot;, *environment_list);
        // environment_list++;
    // }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blsZgP/btsOBPCD4bd/TJu5okGvF6g0KkdggtI0K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blsZgP/btsOBPCD4bd/TJu5okGvF6g0KkdggtI0K0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blsZgP/btsOBPCD4bd/TJu5okGvF6g0KkdggtI0K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblsZgP%2FbtsOBPCD4bd%2FTJu5okGvF6g0KkdggtI0K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;229&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;env_set_get_del.c&lt;/p&gt;
&lt;pre id=&quot;code_1750034121048&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;stdio.h&amp;gt;
#include&amp;lt;stdlib.h&amp;gt;

int main(){

    char env_name[15];
    char env_value[255];
    int overwrite=1;
    printf(&quot;Enter your Variable name:&quot;);
    scanf(&quot;%s&quot;, env_name);
    printf(&quot;Enter the Variable Value: &quot;);
    scanf(&quot;%s&quot;, env_value);
    
    int status = setenv(env_name, env_value, overwrite);

    if(status == 0){
        printf(&quot;Environment variable Created Successfully.!\n&quot;);
    }else if(status == -1){
        printf(&quot;Environment variable creation failed.!\n&quot;);
    }
	printf(&quot;%s=%s\n&quot;,env_name,  getenv(env_name));
	status = unsetenv(env_name);
	printf(&quot;%s=%s\n&quot;,env_name,  getenv(env_name));
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqc42b/btsOBY0kXwc/8J1lOhgqZhbw0nFNccV00K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqc42b/btsOBY0kXwc/8J1lOhgqZhbw0nFNccV00K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqc42b/btsOBY0kXwc/8J1lOhgqZhbw0nFNccV00K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqc42b%2FbtsOBY0kXwc%2F8J1lOhgqZhbw0nFNccV00K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;155&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.mytask.c&lt;/p&gt;
&lt;pre id=&quot;code_1750034901491&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;wait.h&amp;gt;

int main(int argc, char *argv[]) {
	int i, fd;
	
	printf(&quot;%s's PID[%d], PPID[%d]\n&quot;, argv[0], getpid(), getppid());
	
	if((fd = open(&quot;/dev/null&quot;, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1){
		perror(&quot;open&quot;);
		exit(1);
	}
	
#if 1
	dup2(fd, 1);
#endif
	
	for(i=1; i&amp;lt;=atoi(argv[1]); i++) {
		printf(&quot;MyTask_%d!!\n&quot;, i);
		sleep(1);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHFEf/btsOBqpuq51/kkvk0DUm4B6dFzq4yvUvE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHFEf/btsOBqpuq51/kkvk0DUm4B6dFzq4yvUvE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHFEf/btsOBqpuq51/kkvk0DUm4B6dFzq4yvUvE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHFEf%2FbtsOBqpuq51%2Fkkvk0DUm4B6dFzq4yvUvE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;739&quot; height=&quot;388&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.mysystem.c&lt;/p&gt;
&lt;pre id=&quot;code_1750038357141&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(int argc, char *argv[]){
	char cmd_buf[256];
	int ret;
	
	printf(&quot;--------------system start--------------\n&quot;);
#if 1
	strcpy(cmd_buf, &quot;./01.mytask 10&quot;);
#else
	strcpy(cmd_buf, &quot;ps -f&quot;);
#endif
	ret = system(cmd_buf);
	printf(&quot;--------------system end-----------%d-----\n&quot;, ret);
	 
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cukvxw/btsOA2Jzd48/6TkRkRmbjCAxnyFZiSOtL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cukvxw/btsOA2Jzd48/6TkRkRmbjCAxnyFZiSOtL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cukvxw/btsOA2Jzd48/6TkRkRmbjCAxnyFZiSOtL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcukvxw%2FbtsOA2Jzd48%2F6TkRkRmbjCAxnyFZiSOtL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;179&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02-1.mysystem.c&lt;/p&gt;
&lt;pre id=&quot;code_1750038433446&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

void handler(int signo) {
	pid_t exit_pid;
	printf(&quot;handler_pid [%d], handler_ppid [%d]\n&quot;, getpid(), getppid());
	exit_pid = waitpid(-1, NULL, WNOHANG);
	if(exit_pid == -1)
		printf(&quot;waitpid error with ERRNO=%d meaning %s\n&quot;, errno,  strerror(errno));
	else
		printf(&quot;Terminated child PID = %d\n&quot;, exit_pid);
}

int main() {
	signal(SIGCHLD, handler);
	system(&quot;echo Hello World&quot;);
	system(&quot;ps -lf&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bok3cr/btsOCxBaZPF/tegWOS3KIoalgJ7dRuTkFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bok3cr/btsOCxBaZPF/tegWOS3KIoalgJ7dRuTkFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bok3cr/btsOCxBaZPF/tegWOS3KIoalgJ7dRuTkFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbok3cr%2FbtsOCxBaZPF%2FtegWOS3KIoalgJ7dRuTkFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;865&quot; height=&quot;214&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.myfork&lt;/p&gt;
&lt;pre id=&quot;code_1750038571402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int main(void){
	pid_t pid;
	printf(&quot;My PID is %d\n&quot;, getpid());
   
	pid = fork();
	if(pid == -1){
		perror(&quot;fork failed&quot;);
		return 1;
	}
	printf(&quot;Hello World from PID = %d\n&quot;, getpid());
	sleep(120);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wXSwB/btsOA7X41wN/Va22CISrptFVnpPT7hmdVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wXSwB/btsOA7X41wN/Va22CISrptFVnpPT7hmdVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wXSwB/btsOA7X41wN/Va22CISrptFVnpPT7hmdVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwXSwB%2FbtsOA7X41wN%2FVa22CISrptFVnpPT7hmdVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;77&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BRSsU/btsOAIK6myY/dK1y0Gb5staWZhKaHWKU4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BRSsU/btsOAIK6myY/dK1y0Gb5staWZhKaHWKU4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BRSsU/btsOAIK6myY/dK1y0Gb5staWZhKaHWKU4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBRSsU%2FbtsOAIK6myY%2FdK1y0Gb5staWZhKaHWKU4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;66&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03-1.myfork_vm.c&lt;/p&gt;
&lt;pre id=&quot;code_1750038668720&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;

int a=10, b;
int main() {
	int c=100, c2;
	char *d = &quot;I am parent&quot;;
	char *name;
	name = malloc(50);
	name = &quot;cafe&quot;;
	pid_t pid=fork();
	if(pid == 0){
		a=200; b=400; c=600; d=&quot;I am child&quot;; name=&quot;ubuntu&quot;;
	}
	printf(&quot;\e[00m%s[%d] of ppid[%d]\n&quot;, d, getpid(), getppid());
	printf(&quot;paddr(TEXT)=&amp;gt; main:%p\n&quot;, main);
	printf(&quot;paddr(CONST)=&amp;gt; d:%p, d_value:%s\n&quot;, d, d);
	printf(&quot;paddr(DATA)=&amp;gt; a:%p, a_value:%d\n&quot;, &amp;amp;a, *(&amp;amp;a));
	printf(&quot;paddr(BSS)=&amp;gt; b:%p, b_value:%d\n&quot;, &amp;amp;b, *(&amp;amp;b));
	printf(&quot;paddr(STACK)=&amp;gt; c:%p, c_value:%d, d:%p, d_value:%p\n&quot;, &amp;amp;c, *(&amp;amp;c), &amp;amp;d, *(&amp;amp;d));
	printf(&quot;paddr(HEAP)=&amp;gt; name:%p, name_value:%s\n&quot;, &amp;amp;name, name);
	sleep(1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cene3Q/btsOBraTnEu/e6ORQpOEmbCmpZi3bsdOPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cene3Q/btsOBraTnEu/e6ORQpOEmbCmpZi3bsdOPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cene3Q/btsOBraTnEu/e6ORQpOEmbCmpZi3bsdOPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcene3Q%2FbtsOBraTnEu%2Fe6ORQpOEmbCmpZi3bsdOPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;326&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03-2.myfork_zombie.c&lt;/p&gt;
&lt;pre id=&quot;code_1750038798633&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main(int argc, char *argv[]){
	pid_t pid;
	time_t startTimec, startTimep;
	
	if((pid = fork()) &amp;lt; 0){
		perror(&quot;fork&quot;);
		exit(1);
	}else if(pid == 0){		//Child process
		printf(&quot;\e[31mCHILD PROCESS---- (%d)\e[00m\n&quot;, getpid());
		for (startTimec = time(NULL); time(NULL) &amp;lt; startTimec + 8;){
				for(int i=0; i&amp;lt;100000000; i++);
				write(1, &quot;+&quot;, 1);
		}
		sleep(10);
		exit(0);
	}else{					//Parent process
		printf(&quot;\e[00mPARENT PROCESS ---(%d)\n&quot;, getpid());
		for (startTimep = time(NULL); time(NULL) &amp;lt; startTimep + 10;){
				for(int i=0; i&amp;lt;100000000; i++);
				write(1, &quot;*&quot;, 1);
		}
		sleep(100);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xARjM/btsOB8aUcBu/YmM4OE4Lp8qK1aYvuzmkuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xARjM/btsOB8aUcBu/YmM4OE4Lp8qK1aYvuzmkuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xARjM/btsOB8aUcBu/YmM4OE4Lp8qK1aYvuzmkuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxARjM%2FbtsOB8aUcBu%2FYmM4OE4Lp8qK1aYvuzmkuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;837&quot; height=&quot;117&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btMUXi/btsODpWYWK5/weVFb0oVAuN3ckNZCVBTS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btMUXi/btsODpWYWK5/weVFb0oVAuN3ckNZCVBTS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btMUXi/btsODpWYWK5/weVFb0oVAuN3ckNZCVBTS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtMUXi%2FbtsODpWYWK5%2FweVFb0oVAuN3ckNZCVBTS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;120&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03-3.myfork_fd_share.c&lt;/p&gt;
&lt;pre id=&quot;code_1750039014969&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#define BUF_SIZE	128

int main() {
	int fd;
	pid_t pid;
	char buf[BUF_SIZE];
	char *data=&quot;Good Morning&quot;;
	
	fd=open(&quot;file01&quot;, O_RDWR | O_APPEND, 0666);
	pid=fork();
	if(pid == 0){
		printf(&quot;Child FD = %d\n&quot;,fd);
		write(fd, data, strlen(data));
		sleep(1);
		lseek(fd, 0, SEEK_SET);
		read(fd, buf, sizeof(buf));
		printf(&quot;Child : %s\n&quot;, buf);
	}else{
		getchar();
		printf(&quot;Parent FD = %d\n&quot;,fd);
		lseek(fd, 12, SEEK_SET);
		read(fd, buf, sizeof(buf));
		printf(&quot;Parent : %s\n&quot;, buf);
	}
	return 0;
}

/*
* Initially, file01 assumes to contain &quot;hello world&quot; by echoing &quot;hello world &amp;gt; file01&quot;
* then, the output of both parent and chile would be &quot;good morning&quot;
*
* Above example shows that both write and read system call move file offset 
* to the point of ending of writing or reading.
* To see offset, check the return value of lseek.
*
* Any files opened after fork would not be shared between a child and a parent
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nXwva/btsOCyGT6wh/exoRfTXbmHK1ZZsGRlKBy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nXwva/btsOCyGT6wh/exoRfTXbmHK1ZZsGRlKBy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nXwva/btsOCyGT6wh/exoRfTXbmHK1ZZsGRlKBy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnXwva%2FbtsOCyGT6wh%2FexoRfTXbmHK1ZZsGRlKBy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;869&quot; height=&quot;309&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.mywait.c&lt;/p&gt;
&lt;pre id=&quot;code_1750039150690&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main (void) {
	int status;
	pid_t pid;
	
	if((pid=fork()) == 0){
		system(&quot;ps -l&quot;);
		printf(&quot;Child (%d) waiting for either a signal or timeout\n&quot;, getpid());
#if 0
		pause();
#else
		sleep(3);
#endif
		exit(10);
	} else {
		printf(&quot;Parent (%d) waiting for termination of child\n&quot;, getpid());
		pid = wait(&amp;amp;status);
		if (pid == -1)
			perror (&quot;wait&quot;);
		printf(&quot;PID of Child terminated = %d\n&quot;, pid);
		if (WIFEXITED(status))
			printf (&quot;Normal termination with exit status=%d\n&quot;, WEXITSTATUS(status));
		if (WIFSIGNALED(status))
			printf (&quot;terminated by signal=%d%s\n&quot;, WTERMSIG(status), WCOREDUMP(status) ? \
																	&quot; (dumped core)&quot; : &quot;&quot;);
		system(&quot;ps -l&quot;);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMjZE6/btsOCg0Jwhy/8jrIzcVxJwu5Ux5bFxqem1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMjZE6/btsOCg0Jwhy/8jrIzcVxJwu5Ux5bFxqem1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMjZE6/btsOCg0Jwhy/8jrIzcVxJwu5Ux5bFxqem1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMjZE6%2FbtsOCg0Jwhy%2F8jrIzcVxJwu5Ux5bFxqem1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;557&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;05.mywaitpid.c&lt;/p&gt;
&lt;pre id=&quot;code_1750039277985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

int main(void) {
	int status=0;
	pid_t pid, exit_pid;
	time_t startTimec, startTimep;
	
	switch(pid = fork()){
		case -1:		// fork error
			perror(&quot;fork&quot;); 
			exit(1);
		case 0:						//Child 
			for (startTimec = time(NULL); time(NULL) &amp;lt; startTimec + 8;){
				for(int i=0; i&amp;lt;100000000; i++);
				write(1, &quot;+&quot;, 1);
			}
			printf(&quot;\n&quot;);
			system(&quot;ps -lf&quot;);
			exit(0);
		default:					//Parent
			for (startTimep = time(NULL); time(NULL) &amp;lt; startTimep + 10;){
				for(int i=0; i&amp;lt;100000000; i++);
				write(1, &quot;*&quot;, 1);
				exit_pid = waitpid(-1, &amp;amp;status, WNOHANG);
			}
			printf(&quot;\n&quot;);
			system(&quot;ps -lf&quot;);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n2Tkq/btsOAVXZCOa/bpiaDhkWiJ8l4cUlXi6mgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n2Tkq/btsOAVXZCOa/bpiaDhkWiJ8l4cUlXi6mgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n2Tkq/btsOAVXZCOa/bpiaDhkWiJ8l4cUlXi6mgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn2Tkq%2FbtsOAVXZCOa%2FbpiaDhkWiJ8l4cUlXi6mgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;608&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;05-1.mywaitpid.c&lt;/p&gt;
&lt;pre id=&quot;code_1750040019670&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

void handler(int signo) {
	pid_t exit_pid;
	printf(&quot;\nhandler_pid [%d], handler_ppid [%d]\n&quot;, getpid(), getppid());
	exit_pid = waitpid(-1, NULL, WNOHANG);
	if(exit_pid == -1)
		// printf(&quot;waitpid error with ERRNO=%d meaning %s\n&quot;, errno,  strerror(errno));
		perror(&quot;waitpid&quot;);
	else
		printf(&quot;Terminated child PID = %d\n&quot;, exit_pid);
}

int main() {
	pid_t pid1, pid2;
	time_t startTimec, startTimes, startTimep;
	signal(SIGCHLD, handler);
	switch(pid1 = fork()){
		case 0: 
			switch(pid2=fork()){
				case 0:
					printf(&quot;grand-child pid [%d] of ppid [%d] started\n&quot;, getpid(), getppid());
					// for (startTimec = time(NULL); time(NULL) &amp;lt; startTimec + 8;){
						// for(int i=0; i&amp;lt;100000000; i++);
						// write(1, &quot;+&quot;, 1);
					// }
					sleep(5);
					exit(0);
				default:
					printf(&quot;child pid [%d] of ppid [%d] started\n&quot;, getpid(), getppid());
					// for (startTimes = time(NULL); time(NULL) &amp;lt; startTimes + 6;){
						// for(int i=0; i&amp;lt;100000000; i++);
						// write(1, &quot;#&quot;, 1);
					// }
					sleep(10);
					exit(0);
			}
		default: 
			printf(&quot;main pid [%d] of ppid [%d] started\n&quot;, getpid(), getppid());
			for (startTimep = time(NULL); time(NULL) &amp;lt; startTimep + 13;){
					for(int i=0; i&amp;lt;100000000; i++);
					write(1, &quot;*&quot;, 1);
			}
			printf(&quot;\n&quot;);
	} 
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3yt4/btsOBiE30E6/lGcSgwTpZShbP5F0c7D9bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3yt4/btsOBiE30E6/lGcSgwTpZShbP5F0c7D9bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3yt4/btsOBiE30E6/lGcSgwTpZShbP5F0c7D9bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3yt4%2FbtsOBiE30E6%2FlGcSgwTpZShbP5F0c7D9bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;250&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuoNGg/btsOCg0JUZO/fBWTHnuo0ZaSiTRpKA66j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuoNGg/btsOCg0JUZO/fBWTHnuo0ZaSiTRpKA66j1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuoNGg/btsOCg0JUZO/fBWTHnuo0ZaSiTRpKA66j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuoNGg%2FbtsOCg0JUZO%2FfBWTHnuo0ZaSiTRpKA66j1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;923&quot; height=&quot;98&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;05-2.mywatipid.c&lt;/p&gt;
&lt;pre id=&quot;code_1750040165388&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

void handler(int signo) {
	pid_t exit_pid;
	printf(&quot;\nhandler_pid [%d], handler_ppid [%d]\n&quot;, getpid(), getppid());
	exit_pid = waitpid(-1, NULL, WNOHANG);
	if(exit_pid == -1)
		// printf(&quot;waitpid error with ERRNO=%d meaning %s\n&quot;, errno,  strerror(errno));
		perror(&quot;waitpid&quot;);
	else
		printf(&quot;Terminated child PID = %d\n&quot;, exit_pid);
}

int main(void){
	pid_t pid1, pid2;
	time_t startTimec, startTimes, startTimep;
	signal(SIGCHLD, handler);
	switch(pid1 = fork()){
		case 0:						//Child 1
			for (startTimec = time(NULL); time(NULL) &amp;lt; startTimec + 13;){
				for(int i=0; i&amp;lt;100000000; i++);
				write(1, &quot;+&quot;, 1);
			}
			exit(10);
		default:					//Parent
			switch(pid2 = fork()){
				case 0:				//Child 2
					for (startTimes = time(NULL); time(NULL) &amp;lt; startTimes + 6;){
						for(int i=0; i&amp;lt;100000000; i++);
						write(1, &quot;#&quot;, 1);
					}
					exit(11);
				default:			//Parent
					for (startTimep = time(NULL); time(NULL) &amp;lt; startTimep + 15;){
						for(int i=0; i&amp;lt;100000000; i++);
						write(1, &quot;*&quot;, 1);
					}
					printf(&quot;\n&quot;);
			}
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Wi9r/btsOCBqauB9/Lx5aQsOoLpK7KYIKr40OnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Wi9r/btsOCBqauB9/Lx5aQsOoLpK7KYIKr40OnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Wi9r/btsOCBqauB9/Lx5aQsOoLpK7KYIKr40OnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Wi9r%2FbtsOCBqauB9%2FLx5aQsOoLpK7KYIKr40OnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;191&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btCCcm/btsOCneE1WO/TpeDMf4QSPV8kQKqqCy9rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btCCcm/btsOCneE1WO/TpeDMf4QSPV8kQKqqCy9rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btCCcm/btsOCneE1WO/TpeDMf4QSPV8kQKqqCy9rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtCCcm%2FbtsOCneE1WO%2FTpeDMf4QSPV8kQKqqCy9rK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;125&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;06.myexit.c&lt;/p&gt;
&lt;pre id=&quot;code_1750040358229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

static int status;
void handler(int signo) {
	printf (&quot;Signal[%d]='%s' is caughted in handler\n&quot;, signo, strsignal(signo));
	if((waitpid(-1, &amp;amp;status, WUNTRACED | WCONTINUED)) == -1){
        perror(&quot;waitpid&quot;);
    }
	if (WIFEXITED(status)) {
        printf(&quot;exited, status=%d\n&quot;, WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
		if(WTERMSIG(status) &amp;amp;&amp;amp; WCOREDUMP(status))
			printf(&quot;terminated and coredumped by signal[%d]\n&quot; , WTERMSIG(status));
		else 
			printf(&quot;terminated by signal[%d]\n&quot;, WTERMSIG(status));
    } else if (WIFSTOPPED(status)) {
        printf(&quot;stopped by signal[%d]\n&quot;, WSTOPSIG(status));
    } else if (WIFCONTINUED(status)) {
        printf(&quot;continued\n&quot;);
    }
}

void handler2(int signo) {
	extern const char * const sys_siglist[];
	printf (&quot;Signal[%d]='%s' is caughted in handler2\n&quot;, signo, strsignal(signo));
}

int main(int argc, char *argv[]) {
	pid_t pid;
	signal(SIGCHLD, handler);
	
  if ((pid=fork()) == -1) {
    perror(&quot;fork&quot;);
    _exit(EXIT_FAILURE);
  }
	if(pid == 0){            /* Code executed by child */
    printf(&quot;Child PID is %ld\n&quot;, (long) getpid());
    if (argc == 2) {
			signal(SIGINT, handler2);
			pause();  
			sleep(1);
			exit(atoi(argv[1]));
		}
      _exit(10);
	}else{                    /* Code executed by parent */
		getchar();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r1bY3/btsOBfPu4lf/REOClxmzNRPXzVOKniRuLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r1bY3/btsOBfPu4lf/REOClxmzNRPXzVOKniRuLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r1bY3/btsOBfPu4lf/REOClxmzNRPXzVOKniRuLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr1bY3%2FbtsOBfPu4lf%2FREOClxmzNRPXzVOKniRuLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;114&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;23&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m08gD/btsOB0Ro1ak/DiVKEsosKNCZnlQ3AxseA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m08gD/btsOB0Ro1ak/DiVKEsosKNCZnlQ3AxseA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m08gD/btsOB0Ro1ak/DiVKEsosKNCZnlQ3AxseA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm08gD%2FbtsOB0Ro1ak%2FDiVKEsosKNCZnlQ3AxseA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;23&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;23&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JXcio/btsOA3O1kU4/vns9GLVUyH5fnAZsrHUlYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JXcio/btsOA3O1kU4/vns9GLVUyH5fnAZsrHUlYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JXcio/btsOA3O1kU4/vns9GLVUyH5fnAZsrHUlYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJXcio%2FbtsOA3O1kU4%2Fvns9GLVUyH5fnAZsrHUlYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;101&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;21&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C4VKh/btsOBirxkG9/OkgSPoetei3qHUfUMo8k50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C4VKh/btsOBirxkG9/OkgSPoetei3qHUfUMo8k50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C4VKh/btsOBirxkG9/OkgSPoetei3qHUfUMo8k50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC4VKh%2FbtsOBirxkG9%2FOkgSPoetei3qHUfUMo8k50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;519&quot; height=&quot;21&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;21&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt2J3b/btsOBjRuLtj/oKHlKUoUHsrKXS9HsWUcp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt2J3b/btsOBjRuLtj/oKHlKUoUHsrKXS9HsWUcp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt2J3b/btsOBjRuLtj/oKHlKUoUHsrKXS9HsWUcp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt2J3b%2FbtsOBjRuLtj%2FoKHlKUoUHsrKXS9HsWUcp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;82&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;82&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;22&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mb2SY/btsOCCP8PQ6/tskr802Q9adzWCpC4XZnsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mb2SY/btsOCCP8PQ6/tskr802Q9adzWCpC4XZnsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mb2SY/btsOCCP8PQ6/tskr802Q9adzWCpC4XZnsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMb2SY%2FbtsOCCP8PQ6%2Ftskr802Q9adzWCpC4XZnsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;22&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;22&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gmqdn/btsODnkzo6o/FvULyAemR0FpQVSW8S2JV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gmqdn/btsODnkzo6o/FvULyAemR0FpQVSW8S2JV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gmqdn/btsODnkzo6o/FvULyAemR0FpQVSW8S2JV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGmqdn%2FbtsODnkzo6o%2FFvULyAemR0FpQVSW8S2JV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;82&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;82&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;06-1.myexit.c&lt;/p&gt;
&lt;pre id=&quot;code_1750040559068&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;

void hello() {
   printf(&quot;Hello\n&quot;);
}
void world(int exit_code, void *arg) {
   printf(&quot;world with CODE=%d and MSG=%s\n&quot;, exit_code, (char *)arg);
}

int main() {
   /* register the termination function */
   atexit(hello);
   on_exit(world, &quot;Good Bye&quot;);
	 atexit(hello);
   
   printf(&quot;Starting  main program...\n&quot;);

   printf(&quot;Exiting main program...\n&quot;);
   
   // exit(10);
   _exit(20);
   // return 100;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EFHzr/btsODGK4QpD/rTXWvs4lywT7ahjIGvkXHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EFHzr/btsODGK4QpD/rTXWvs4lywT7ahjIGvkXHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EFHzr/btsODGK4QpD/rTXWvs4lywT7ahjIGvkXHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEFHzr%2FbtsODGK4QpD%2FrTXWvs4lywT7ahjIGvkXHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;701&quot; height=&quot;102&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;06-1.myexit.c (exit(10);)&lt;/p&gt;
&lt;pre id=&quot;code_1750040600971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;

void hello() {
   printf(&quot;Hello\n&quot;);
}
void world(int exit_code, void *arg) {
   printf(&quot;world with CODE=%d and MSG=%s\n&quot;, exit_code, (char *)arg);
}

int main() {
   /* register the termination function */
   atexit(hello);
   on_exit(world, &quot;Good Bye&quot;);
	 atexit(hello);
   
   printf(&quot;Starting  main program...\n&quot;);

   printf(&quot;Exiting main program...\n&quot;);
   
   exit(10);
   // _exit(20);
   // return 100;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcfOQ8/btsOAHZMkAK/VVIppxcN8J2ZKfxGciqA0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcfOQ8/btsOAHZMkAK/VVIppxcN8J2ZKfxGciqA0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcfOQ8/btsOAHZMkAK/VVIppxcN8J2ZKfxGciqA0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcfOQ8%2FbtsOAHZMkAK%2FVVIppxcN8J2ZKfxGciqA0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;155&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;06-2.myexit.c&lt;/p&gt;
&lt;pre id=&quot;code_1750040806457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

void handler(int signo) {
	printf (&quot;signal[%d]='%s' is caughted\n&quot;, signo, strsignal(signo));
	// exit(20);
}

void exit_handler(int exit_code, void *arg){
	printf(&quot;PID=%d is exited with CODE=%d and MSG=%s\n&quot;, getpid(), exit_code, (char *)arg);
}

int main(int argc, char *argv[]) {
	signal(SIGCHLD, handler);
	on_exit(exit_handler, &quot;exit function ended&quot;);
	switch (fork()){
		case -1:
			perror(&quot;fork&quot;);
			exit(30);
		case 0:
			printf(&quot;Child PID = %ld, Parend PID = %d \n&quot;, (long) getpid(), getppid());
			if (argc == 2) {
				exit(atoi(argv[1]));
			}
			_exit(10);
		default:
			getchar();
			exit(150);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;23&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVKw9T/btsOBD92wPV/a1Ho7N0kMUsaPIX3Y7y0KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVKw9T/btsOBD92wPV/a1Ho7N0kMUsaPIX3Y7y0KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVKw9T/btsOBD92wPV/a1Ho7N0kMUsaPIX3Y7y0KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVKw9T%2FbtsOBD92wPV%2Fa1Ho7N0kMUsaPIX3Y7y0KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;23&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;23&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnql7j/btsOCPn88Il/yUjjMV7PeZpzAOyZ5KMMSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnql7j/btsOCPn88Il/yUjjMV7PeZpzAOyZ5KMMSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnql7j/btsOCPn88Il/yUjjMV7PeZpzAOyZ5KMMSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcnql7j%2FbtsOCPn88Il%2FyUjjMV7PeZpzAOyZ5KMMSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;704&quot; height=&quot;117&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwg8Ud/btsOA5st9NH/k8t0tLvT2HloNtmk0mdmH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwg8Ud/btsOA5st9NH/k8t0tLvT2HloNtmk0mdmH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwg8Ud/btsOA5st9NH/k8t0tLvT2HloNtmk0mdmH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwg8Ud%2FbtsOA5st9NH%2Fk8t0tLvT2HloNtmk0mdmH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;80&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;08.mydaemon.c&lt;/p&gt;
&lt;pre id=&quot;code_1750044896436&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

void daemonize(void) {
    pid_t pid = fork();
    if (pid &amp;lt; 0) {
        perror(&quot;fork failed&quot;);
        exit(EXIT_FAILURE);
    }
    if (pid &amp;gt; 0) {
        /* Parent exits, child continues */
        exit(EXIT_SUCCESS);
    }

    /* Become session leader to detach from terminal */
    if (setsid() &amp;lt; 0) {
        perror(&quot;setsid failed&quot;);
        exit(EXIT_FAILURE);
    }

    /* Clear file creation mask */
    umask(0);

    /* Change working directory to root */
    if (chdir(&quot;/&quot;) &amp;lt; 0) {
        perror(&quot;chdir failed&quot;);
        exit(EXIT_FAILURE);
    }

    /* Close inherited file descriptors */
    long max_fd = sysconf(_SC_OPEN_MAX);
    if (max_fd == -1) {
        max_fd = 1024;
    }
    for (long fd = 0; fd &amp;lt; max_fd; fd++) {
        close(fd);
    }

    /* Redirect stdin, stdout, stderr to /dev/null */
    open(&quot;/dev/null&quot;, O_RDONLY);
    open(&quot;/dev/null&quot;, O_RDWR);
    open(&quot;/dev/null&quot;, O_RDWR);
}

int main(void) {
    FILE *logfp;

    daemonize();

    /* Open log file after daemonization */
    logfp = fopen(&quot;/tmp/mydaemon.log&quot;, &quot;a+&quot;);
    if (!logfp) {
        exit(EXIT_FAILURE);
    }

    /* Periodically write to log */
    while (1) {
        time_t now = time(NULL);
        struct tm *tm_info = localtime(&amp;amp;now);
        char time_str[64];
        strftime(time_str, sizeof(time_str), &quot;%a %b %d %T %Y&quot;, tm_info);
        fprintf(logfp, &quot;Mydaemon alive at %s\n&quot;, time_str);
        fflush(logfp);
        sleep(5);
    }

    /* Clean up */
    fclose(logfp);
    return EXIT_SUCCESS;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXu0py/btsODj3Iz8c/fVAk7Y1acuqmAceZZG1oQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXu0py/btsODj3Iz8c/fVAk7Y1acuqmAceZZG1oQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXu0py/btsODj3Iz8c/fVAk7Y1acuqmAceZZG1oQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXu0py%2FbtsODj3Iz8c%2FfVAk7Y1acuqmAceZZG1oQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;883&quot; height=&quot;402&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 process에서 ppid를 찾아 올라가서 1,2프로세스까지 ppid를 찾아 올라가는 프로그램 작성&lt;/p&gt;
&lt;pre id=&quot;code_1750052765710&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

// Read PPid from /proc/[pid]/status
long get_ppid(long pid) {
    char path[64], line[128];
    FILE *f;
    snprintf(path, sizeof(path), &quot;/proc/%ld/status&quot;, pid);
    if ((f = fopen(path, &quot;r&quot;)) == NULL) return -1;
    while (fgets(line, sizeof(line), f)) {
        long p;
        if (sscanf(line, &quot;PPid:\t%ld&quot;, &amp;amp;p) == 1) {
            fclose(f);
            return p;
        }
    }
    fclose(f);
    return -1;
}

int main(void) {
    long pid = getpid(), ppid;
    printf(&quot;01.current : %ld&quot;, pid);

    while ((ppid = get_ppid(pid)) &amp;gt; 2) {
        printf(&quot; &amp;rarr; %ld&quot;, ppid);
        pid = ppid;
    }
    if (ppid &amp;gt; 0)
        printf(&quot; &amp;rarr; %ld&quot;, ppid);

    printf(&quot;\n&quot;);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xflaP/btsOBqQ9IHV/e6gC1JNPKsK4aGKIIoM8K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xflaP/btsOBqQ9IHV/e6gC1JNPKsK4aGKIIoM8K0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xflaP/btsOBqQ9IHV/e6gC1JNPKsK4aGKIIoM8K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxflaP%2FbtsOBqQ9IHV%2Fe6gC1JNPKsK4aGKIIoM8K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;80&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;powershell 관리자권한으로 실행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vaq6U/btsOBPpRLzR/MOKGFmXkykeT9Nhs6a1vjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vaq6U/btsOBPpRLzR/MOKGFmXkykeT9Nhs6a1vjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vaq6U/btsOBPpRLzR/MOKGFmXkykeT9Nhs6a1vjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvaq6U%2FbtsOBPpRLzR%2FMOKGFmXkykeT9Nhs6a1vjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;72&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdaXsf/btsOD0iH0co/KFPScwQlx0BsmoaONl4aE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdaXsf/btsOD0iH0co/KFPScwQlx0BsmoaONl4aE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdaXsf/btsOD0iH0co/KFPScwQlx0BsmoaONl4aE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdaXsf%2FbtsOD0iH0co%2FKFPScwQlx0BsmoaONl4aE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1075&quot; height=&quot;685&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qO6b4/btsOCy1Mgmb/wNanDf5BCmNNbgmAFk9YJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qO6b4/btsOCy1Mgmb/wNanDf5BCmNNbgmAFk9YJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qO6b4/btsOCy1Mgmb/wNanDf5BCmNNbgmAFk9YJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqO6b4%2FbtsOCy1Mgmb%2FwNanDf5BCmNNbgmAFk9YJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;261&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VSCode 연동&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wGxaw/btsOD28LjKA/m03EK0LzWmKQH7PY0JQZZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wGxaw/btsOD28LjKA/m03EK0LzWmKQH7PY0JQZZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wGxaw/btsOD28LjKA/m03EK0LzWmKQH7PY0JQZZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwGxaw%2FbtsOD28LjKA%2Fm03EK0LzWmKQH7PY0JQZZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1317&quot; height=&quot;796&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/518</guid>
      <comments>https://hotari.tistory.com/518#entry518comment</comments>
      <pubDate>Mon, 16 Jun 2025 16:52:06 +0900</pubDate>
    </item>
    <item>
      <title>3일차</title>
      <link>https://hotari.tistory.com/517</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.13&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;00.signalprint.c&lt;/p&gt;
&lt;pre id=&quot;code_1749775811663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

const char *binary[16] = {
    [ 0] = &quot;0000&quot;, [ 1] = &quot;0001&quot;, [ 2] = &quot;0010&quot;, [ 3] = &quot;0011&quot;,
    [ 4] = &quot;0100&quot;, [ 5] = &quot;0101&quot;, [ 6] = &quot;0110&quot;, [ 7] = &quot;0111&quot;,
    [ 8] = &quot;1000&quot;, [ 9] = &quot;1001&quot;, [10] = &quot;1010&quot;, [11] = &quot;1011&quot;,
    [12] = &quot;1100&quot;, [13] = &quot;1101&quot;, [14] = &quot;1110&quot;, [15] = &quot;1111&quot;,
};

void print_byte(int byte){
    // printf(&quot;%s%s&quot;, bit_rep[byte &amp;gt;&amp;gt; 4], bit_rep[byte &amp;amp; 0x0F]);
	printf(&quot;%s&quot;, binary[byte &amp;amp; 0x0F]);
}

void print_sigset_t(sigset_t *set){
	int i;

	i = SIGRTMAX;
	// i = 32;
	do {
		int x = 0;
		i -= 4;
		if (sigismember(set, i+1)) x |= 1;
		if (sigismember(set, i+2)) x |= 2;
		if (sigismember(set, i+3)) x |= 4;
		if (sigismember(set, i+4)) x |= 8;
		// printf(&quot;%x&quot;, x);
		print_byte(x);
	} while (i &amp;gt;= 4); 
	printf(&quot;\n&quot;);
}

int main(int argc, char **argv)
{
	sigset_t set;
	sigemptyset(&amp;amp;set);
	/* add signals to set */
	sigaddset(&amp;amp;set, SIGINT); 		//sig # 2
	sigaddset(&amp;amp;set, SIGHUP);		//sig # 1
	sigaddset(&amp;amp;set, SIGALRM);		//sig # 14
	sigaddset(&amp;amp;set, SIGFPE);		//sig # 8
	sigaddset(&amp;amp;set, SIGABRT);		//sig # 6
	/* dump signals from set*/	
	print_sigset_t(&amp;amp;set);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR9dqO/btsOAicFs0J/7yRJKHmqqhczyrKD1FlZi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR9dqO/btsOAicFs0J/7yRJKHmqqhczyrKD1FlZi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR9dqO/btsOAicFs0J/7yRJKHmqqhczyrKD1FlZi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR9dqO%2FbtsOAicFs0J%2F7yRJKHmqqhczyrKD1FlZi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;745&quot; height=&quot;79&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;79&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.signal.c&lt;/p&gt;
&lt;pre id=&quot;code_1749775841886&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int repeat = 0;

void handler(int signo){
	fprintf(stderr, &quot;Signal handler triggered %d times (signum=%d)\n&quot;, repeat++, signo);
	if(repeat &amp;gt;= 5)
		signal(SIGINT, SIG_DFL);
	if(signo == 15){
	
		sleep(3);
		exit(0);
	}
}

int main(int argc, char *argv[]){
	signal(SIGINT, handler);
	signal(SIGQUIT, handler);
	signal(SIGTERM, handler);
	signal(SIGTSTP, handler);
	while(1){
		printf(&quot;signal interrupt test --- %d\n&quot;, repeat);
		sleep(1);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uPfyk/btsOy0q2dVy/cLun7l7uD1Gzkrp5mieOC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uPfyk/btsOy0q2dVy/cLun7l7uD1Gzkrp5mieOC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uPfyk/btsOy0q2dVy/cLun7l7uD1Gzkrp5mieOC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuPfyk%2FbtsOy0q2dVy%2FcLun7l7uD1Gzkrp5mieOC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;690&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02.mypause.c&lt;/p&gt;
&lt;pre id=&quot;code_1749776140827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;

static void handler (int signo){
	printf (&quot;[%d] signal is caughted\n&quot;, signo);
}

int main (void){
	signal(SIGRTMIN, handler);
	signal(SIGRTMIN+1, handler);
	for (;;){
		for(int i=0; i&amp;lt;5; i++){
			printf(&quot;I am running  --- %d\n&quot;, i);
			sleep(1);
		}
		printf(&quot;Now I am waiting for a signal --- &quot;);
		pause();
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXPxXR/btsOzeI6SbH/zrmKZ66ccTEyTY31YfXEAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXPxXR/btsOzeI6SbH/zrmKZ66ccTEyTY31YfXEAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXPxXR/btsOzeI6SbH/zrmKZ66ccTEyTY31YfXEAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXPxXR%2FbtsOzeI6SbH%2FzrmKZ66ccTEyTY31YfXEAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;266&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;29&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPX1m3/btsOzIXfIJ6/FAmQwTxn8wNNrqlEyLaNmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPX1m3/btsOzIXfIJ6/FAmQwTxn8wNNrqlEyLaNmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPX1m3/btsOzIXfIJ6/FAmQwTxn8wNNrqlEyLaNmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPX1m3%2FbtsOzIXfIJ6%2FFAmQwTxn8wNNrqlEyLaNmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;660&quot; height=&quot;29&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;29&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;01.mysignal_handler.c&lt;/p&gt;
&lt;pre id=&quot;code_1749779031347&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

static int cnt_int = 0;
static int cnt_quit = 0;
static int cnt_term = 0;
static int cnt_tstp = 0;

void handler_sigint(int signo){
	fprintf(stderr, &quot;Signal handler triggered %d times (signum=%d)\n&quot;, cnt_int++, signo);
	if(cnt_int &amp;gt;= 5)
		signal(SIGINT, SIG_DFL);
	if(signo == 15){
	
		sleep(3);
		exit(0);
	}
}

void handler_sigquit(int signo){
	fprintf(stderr, &quot;Signal handler triggered %d times (signum=%d)\n&quot;, cnt_quit++, signo);
	if(cnt_quit &amp;gt;= 5)
		signal(SIGQUIT, SIG_DFL);
	if(signo == 15){

		sleep(3);
		exit(0);
	}
}

void handler_sigterm(int signo) {

    cnt_term++;

    fprintf(stderr, &quot;[SIGTERM] count=%d, signo=%d\n&quot;, cnt_term, signo);

    if (cnt_term &amp;gt;= 5) {
	    signal(SIGTERM, SIG_DFL);
    }
}

void handler_sigtstp(int signo){
	fprintf(stderr, &quot;Signal handler triggered %d times (signum=%d)\n&quot;, cnt_tstp++, signo);
	if(cnt_tstp &amp;gt;= 5)
		signal(SIGTSTP, SIG_DFL);
	if(signo == 15){

		sleep(3);
		exit(0);
	}
}

int main(int argc, char *argv[]){
	signal(SIGINT, handler_sigint);
	signal(SIGQUIT, handler_sigquit);
	signal(SIGTERM, handler_sigterm);
	signal(SIGTSTP, handler_sigtstp);
	while(1){
		printf(&quot;signal interrupt test --- INT:%d, QUIT:%d, TERM:%d, TSTP:%d\n&quot;, cnt_int, cnt_quit, cnt_term, cnt_tstp);
		sleep(1);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctrl+c : int&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctrl+\ : tstp&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctrl+z : quit&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;765&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k81Wh/btsOzcdGvkS/a1AwBXAe8iBmUf3eJOoiEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k81Wh/btsOzcdGvkS/a1AwBXAe8iBmUf3eJOoiEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k81Wh/btsOzcdGvkS/a1AwBXAe8iBmUf3eJOoiEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk81Wh%2FbtsOzcdGvkS%2Fa1AwBXAe8iBmUf3eJOoiEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;765&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;765&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kill : tstp&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qnuok/btsOybs3PTS/8JfT4sX42rvLMFAx9kc2y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qnuok/btsOybs3PTS/8JfT4sX42rvLMFAx9kc2y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qnuok/btsOybs3PTS/8JfT4sX42rvLMFAx9kc2y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqnuok%2FbtsOybs3PTS%2F8JfT4sX42rvLMFAx9kc2y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;62&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;03.mykill.c&lt;/p&gt;
&lt;pre id=&quot;code_1749779998464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int main(int argc, char *argv[]){
	
#if 1
	if(argc &amp;lt; 3){
		fprintf(stderr, &quot;Usage: %s &amp;lt;pid_#&amp;gt; &amp;lt;sig_#&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	if(kill(atoi(argv[1]), atoi(argv[2])) == -1){
		if(errno == EINVAL){
			printf(&quot;Invalid signal\n&quot;);
		}else if(errno == EPERM){
			printf(&quot;No Permission\n&quot;);
		}else if(errno == ESRCH){
			printf(&quot;No such process\n&quot;);
		}
	}
#else
	if(argc &amp;lt; 2){
		fprintf(stderr, &quot;Usage: %s &amp;lt;pid_#&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	for (int i=34; i&amp;lt;64; i++){
		kill(atoi(argv[1]), i);
		sleep(3);
	}
#endif
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SGi7J/btsOyddjuAr/QZPPhfZoyWE6tZyEpQgyXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SGi7J/btsOyddjuAr/QZPPhfZoyWE6tZyEpQgyXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SGi7J/btsOyddjuAr/QZPPhfZoyWE6tZyEpQgyXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSGi7J%2FbtsOyddjuAr%2FQZPPhfZoyWE6tZyEpQgyXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;253&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bblVM0/btsOAiwYjXI/GyIKoovoukKos5WSJwGYHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bblVM0/btsOAiwYjXI/GyIKoovoukKos5WSJwGYHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bblVM0/btsOAiwYjXI/GyIKoovoukKos5WSJwGYHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbblVM0%2FbtsOAiwYjXI%2FGyIKoovoukKos5WSJwGYHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;932&quot; height=&quot;254&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.myraise.c&lt;/p&gt;
&lt;pre id=&quot;code_1749781595689&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;

void handler(int signo){
	printf(&quot;Received Signal no - %d\n&quot;, signo);
}

int main(int argc, char *argv[]){
	int a,b;
	
	for(int i=1; i&amp;lt;64; i++){
		if(signal(i, handler) == SIG_ERR){
			fprintf (stderr, &quot;Cannot handle signal=%d\n&quot;, i);
		} 
	}
	for(int i=0; i&amp;lt;64; i++){
		if(i!=9 &amp;amp;&amp;amp; i!=32 &amp;amp;&amp;amp; i!=33){
			// kill(getpid(), i);
			raise(i);
			sleep(1);
		}
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c32mBR/btsOysBlmSH/PM46M3uSAlodNwfZzDrmE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c32mBR/btsOysBlmSH/PM46M3uSAlodNwfZzDrmE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c32mBR/btsOysBlmSH/PM46M3uSAlodNwfZzDrmE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc32mBR%2FbtsOysBlmSH%2FPM46M3uSAlodNwfZzDrmE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;466&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;921&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uRwjH/btsOypSaWmp/01eHlLkFHqrOMNkUUOBSAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uRwjH/btsOypSaWmp/01eHlLkFHqrOMNkUUOBSAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uRwjH/btsOypSaWmp/01eHlLkFHqrOMNkUUOBSAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuRwjH%2FbtsOypSaWmp%2F01eHlLkFHqrOMNkUUOBSAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;921&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;921&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;04.myraise_kill.c&lt;/p&gt;
&lt;pre id=&quot;code_1749783750492&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;

int count = 0;

void handler(int signo){
	printf(&quot;Received Signal no - %d\n&quot;, signo);
    if(signo == 34){
        count++;
        fprintf (stderr, &quot;signo34, count up, count : %d\n&quot;, count);
    }else if(signo == 35){
        count--;
        fprintf (stderr, &quot;signo35, count down, count : %d\n&quot;, count);
    }
}

void handler34(int signo){
	count++;
        fprintf (stderr, &quot;signo34, count up, count : %d\n&quot;, count);
}

void handler35(int signo){
	count--;
        fprintf (stderr, &quot;signo35, count down, count : %d\n&quot;, count);
}

int main(int argc, char *argv[]){
	int a,b;

    printf(&quot;pid : %d\n&quot;, getpid());

    signal(34, handler34);
    signal(35, handler35);
	

    while(1){
        sleep(1);
    }

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfP1VO/btsOz9z7dj8/GUcnUnIVkPvJo3cfkvj7Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfP1VO/btsOz9z7dj8/GUcnUnIVkPvJo3cfkvj7Y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfP1VO/btsOz9z7dj8/GUcnUnIVkPvJo3cfkvj7Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfP1VO%2FbtsOz9z7dj8%2FGUcnUnIVkPvJo3cfkvj7Y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;162&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vzhQ2/btsOAwu2BTP/4EtRNfh4LSPG4VKg386De0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vzhQ2/btsOAwu2BTP/4EtRNfh4LSPG4VKg386De0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vzhQ2/btsOAwu2BTP/4EtRNfh4LSPG4VKg386De0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvzhQ2%2FbtsOAwu2BTP%2F4EtRNfh4LSPG4VKg386De0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;139&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;05.setprocmask.c&lt;/p&gt;
&lt;pre id=&quot;code_1749785488221&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &quot;signalprint.h&quot;

void handler(int signo){
	printf (&quot;[%d] signal is caughted\n&quot;, signo);
}

int main(void) {
	sigset_t set1, set2, set3, set4, oldset;
	
	signal(SIGQUIT, handler);  // ctrl + \
	sleep(2);
	sigemptyset(&amp;amp;set1);	
	sigaddset(&amp;amp;set1, 2);
	printf(&quot;signals in set1 are blocked\n&quot;);
	printf(&quot;set1 : &quot;);
	print_sigset_t(&amp;amp;set1);	
	sigprocmask(SIG_BLOCK, &amp;amp;set1, &amp;amp;oldset);
	printf(&quot;oldset: &quot;);
	print_sigset_t(&amp;amp;oldset);
	
	sleep(5);
	sigemptyset(&amp;amp;set2);							
	sigaddset(&amp;amp;set2, SIGQUIT);  
	printf(&quot;\nSignals in set2 are blocked\n&quot;);	
	printf(&quot;set2 : &quot;);
	print_sigset_t(&amp;amp;set2);	
	sigprocmask(SIG_BLOCK, &amp;amp;set2, &amp;amp;oldset);
	printf(&quot;oldset: &quot;);
	print_sigset_t(&amp;amp;oldset);
	
	sleep(5);
	sigemptyset(&amp;amp;set4);							
	sigaddset(&amp;amp;set4, SIGRTMIN);  
	printf(&quot;\nSignals in set4 are now blocked\n&quot;);	
	printf(&quot;set4 : &quot;);
	print_sigset_t(&amp;amp;set4);	
	sigprocmask(SIG_BLOCK, &amp;amp;set4, &amp;amp;oldset);
	printf(&quot;oldset: &quot;);
	print_sigset_t(&amp;amp;oldset);

	sleep(5);
	sigfillset(&amp;amp;set3);							
	printf(&quot;\nThe set of blocked signal is replaced by set3\n&quot;);
	printf(&quot;set3 : &quot;);
	print_sigset_t(&amp;amp;set3);
	sigprocmask(SIG_SETMASK, &amp;amp;set3,  &amp;amp;oldset);	
	printf(&quot;oldset : &quot;);
	print_sigset_t(&amp;amp;oldset);
	
	sleep(5);
	printf(&quot;\nSignals in oldset are now unblocked\n&quot;);
	sigprocmask(SIG_UNBLOCK, &amp;amp;oldset, NULL);			
		
	for(int i=0; ; i++){    
		printf(&quot;Hello Signal --- %d\n&quot;, i);    
		sleep(1);  
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;signalprint.h&lt;/p&gt;
&lt;pre id=&quot;code_1749785513007&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void print_sigset_t(sigset_t*set);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;00.signalprint.c&lt;/p&gt;
&lt;pre id=&quot;code_1749785539727&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

const char *binary[16] = {
    [ 0] = &quot;0000&quot;, [ 1] = &quot;0001&quot;, [ 2] = &quot;0010&quot;, [ 3] = &quot;0011&quot;,
    [ 4] = &quot;0100&quot;, [ 5] = &quot;0101&quot;, [ 6] = &quot;0110&quot;, [ 7] = &quot;0111&quot;,
    [ 8] = &quot;1000&quot;, [ 9] = &quot;1001&quot;, [10] = &quot;1010&quot;, [11] = &quot;1011&quot;,
    [12] = &quot;1100&quot;, [13] = &quot;1101&quot;, [14] = &quot;1110&quot;, [15] = &quot;1111&quot;,
};

void print_byte(int byte){
    // printf(&quot;%s%s&quot;, bit_rep[byte &amp;gt;&amp;gt; 4], bit_rep[byte &amp;amp; 0x0F]);
	printf(&quot;%s&quot;, binary[byte &amp;amp; 0x0F]);
}

void print_sigset_t(sigset_t *set){
	int i;

	i = SIGRTMAX;
	// i = 32;
	do {
		int x = 0;
		i -= 4;
		if (sigismember(set, i+1)) x |= 1;
		if (sigismember(set, i+2)) x |= 2;
		if (sigismember(set, i+3)) x |= 4;
		if (sigismember(set, i+4)) x |= 8;
		// printf(&quot;%x&quot;, x);
		print_byte(x);
	} while (i &amp;gt;= 4); 
	printf(&quot;\n&quot;);
}

/*
int main(int argc, char **argv)
{
	sigset_t set;
	sigemptyset(&amp;amp;set);
	/* add signals to set
	sigaddset(&amp;amp;set, SIGINT); 		//sig # 2
	sigaddset(&amp;amp;set, SIGHUP);		//sig # 1
	sigaddset(&amp;amp;set, SIGALRM);		//sig # 14
	sigaddset(&amp;amp;set, SIGFPE);		//sig # 8
	sigaddset(&amp;amp;set, SIGABRT);		//sig # 6
	/* dump signals from set	
	print_sigset_t(&amp;amp;set);
}
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cimOcI/btsOyHd5uAp/tpff9fqqmbntzTEPMDQD41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cimOcI/btsOyHd5uAp/tpff9fqqmbntzTEPMDQD41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cimOcI/btsOyHd5uAp/tpff9fqqmbntzTEPMDQD41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcimOcI%2FbtsOyHd5uAp%2Ftpff9fqqmbntzTEPMDQD41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;518&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;06.mysigsuspend.c&lt;/p&gt;
&lt;pre id=&quot;code_1749785959458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt; 
#include &amp;lt;signal.h&amp;gt; 
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &quot;signalprint.h&quot;

static void handler(int signo) { 
	printf (&quot;[%d] signal is caughted\n&quot;, signo);
} 

int main() { 
	sigset_t set1,set2; 
	signal(SIGINT, handler); 
	signal(SIGRTMAX-1, handler);
	
	sigemptyset(&amp;amp;set1); 
	sigaddset(&amp;amp;set1,SIGINT); 
	sigaddset(&amp;amp;set1,SIGRTMAX-1); 
	
	sigfillset(&amp;amp;set2); 
	sigdelset(&amp;amp;set2, SIGINT);
	sigdelset(&amp;amp;set2, SIGRTMAX-1);
	
	sigprocmask(SIG_BLOCK,&amp;amp;set1,NULL); 
	print_sigset_t(&amp;amp;set1);
	print_sigset_t(&amp;amp;set2);
	
	for(int i=0; i&amp;lt;5; i++){
		printf(&quot;Critical Region 1 is running --- %d\n&quot;, i);
		sleep(1);
	}
#if 1
	printf(&quot;Waiting for a signal  ----------------- \n&quot;);
	sigsuspend(&amp;amp;set2);
#else
	sigprocmask(SIG_SETMASK, &amp;amp;set2, NULL);
	printf(&quot;Waiting for a signal  ----------------- \n&quot;);
	pause();
#endif
	for(int i=0; i&amp;lt;5; i++){
		printf(&quot;Critical Region 2 is running --- %d\n&quot;, i);
		sleep(1);
	}
	exit(0); 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eiMs4N/btsOAxguNCH/1aKTtGcEaLYmp0UCKbGso0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eiMs4N/btsOAxguNCH/1aKTtGcEaLYmp0UCKbGso0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eiMs4N/btsOAxguNCH/1aKTtGcEaLYmp0UCKbGso0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeiMs4N%2FbtsOAxguNCH%2F1aKTtGcEaLYmp0UCKbGso0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;925&quot; height=&quot;310&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;07.mysigaction.c&lt;/p&gt;
&lt;pre id=&quot;code_1749792916715&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &quot;signalprint.h&quot;

void handler(int sig){ㅐ 
	sigset_t sigset;
    sigprocmask(SIG_SETMASK, NULL, &amp;amp;sigset);
	printf(&quot;blocked signal set : &quot;);
	print_sigset_t(&amp;amp;sigset);
	for(int i=1; i&amp;lt;=3; i++) {
		printf(&quot;handler_%d!!\n&quot;, i);
		sleep(1);
	}
}
	
int main(void){
	struct sigaction act, oldact;
	
	act.sa_handler = handler;
	sigemptyset(&amp;amp;act.sa_mask);
	sigaddset(&amp;amp;act.sa_mask,SIGQUIT);
	
	// act.sa_flags=SA_NODEFER;
	act.sa_flags=SA_RESTART;
	// act.sa_flags=SA_RESETHAND;
	sigaction(SIGINT, &amp;amp;act, &amp;amp;oldact);
	
	for(int i=1; ; i++){
		printf(&quot;signal test --- %d\n&quot;, i);
		sleep(2);
	}
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NCY6R/btsOAGZo8Zv/kJhrqTItGyWsvQHlASZ8b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NCY6R/btsOAGZo8Zv/kJhrqTItGyWsvQHlASZ8b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NCY6R/btsOAGZo8Zv/kJhrqTItGyWsvQHlASZ8b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNCY6R%2FbtsOAGZo8Zv%2FkJhrqTItGyWsvQHlASZ8b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;518&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;08.mysigalarm.c&lt;/p&gt;
&lt;pre id=&quot;code_1749793075362&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt; 
#include &amp;lt;stdlib.h&amp;gt; 
#include &amp;lt;unistd.h&amp;gt; 
#include &amp;lt;signal.h&amp;gt; 
#include &amp;lt;string.h&amp;gt;

void alarm_handler(int signo){
	printf(&quot;Time over, try again later---\n&quot;);
	exit(0);
}

int main(int argc, char *argv[]){
	char buf[512];
	char *passwd = &quot;hello&quot;;
	struct sigaction act;
	if(argc &amp;lt;2){
		fprintf(stderr, &quot;Usage: %s &amp;lt;timelimit&amp;gt;\n&quot;, argv[0]);
		exit(1);
	}
	act.sa_handler = alarm_handler;
	sigaction(SIGALRM, &amp;amp;act, NULL);
	alarm(atoi(argv[1]));
	while(1){
		printf(&quot;Input password: &quot;);
		scanf(&quot;%s&quot;, buf);
		if(!strcmp(buf, passwd)){
			printf(&quot;Success\n&quot;);
			break;
		}else{
			printf(&quot;Fail\n&quot;);
		}
	}
	printf(&quot;Main function -----\n&quot;);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TvDXb/btsOBgy05qW/NIry5U5nWhfF1RWgTWeUUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TvDXb/btsOBgy05qW/NIry5U5nWhfF1RWgTWeUUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TvDXb/btsOBgy05qW/NIry5U5nWhfF1RWgTWeUUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTvDXb%2FbtsOBgy05qW%2FNIry5U5nWhfF1RWgTWeUUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;118&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10.mysigpending.c&lt;/p&gt;
&lt;pre id=&quot;code_1749793171855&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &quot;signalprint.h&quot;

static void handler(int signo) { 
	printf(&quot;Signal #(%d) is caught\n&quot;, signo); 
}

int main( void){
	sigset_t sigset, oldset, pendingset;
	for(int i=1; i&amp;lt;=64; i++){
		signal(i, handler);
	}
	sigfillset(&amp;amp;sigset);
	sigprocmask(SIG_SETMASK, &amp;amp;sigset, &amp;amp;oldset);
	print_sigset_t(&amp;amp;oldset);
	int i=0;
	while(1){
		printf( &quot;I am running --- %d\n&quot;, i++);
		sleep(1);
		if (sigpending(&amp;amp;pendingset) == 0){
			print_sigset_t(&amp;amp;pendingset);
			if (sigismember(&amp;amp;pendingset, SIGINT)){
				printf( &quot;SIGINT was pended --- end of loop.\n&quot;);
				break;
			}
			if(sigismember(&amp;amp;pendingset, SIGTSTP)){
				printf( &quot;SIGTSTP was pended --- end of loop.\n&quot;);
				break;
			}
		}
   }
	 sigprocmask(SIG_SETMASK, &amp;amp;oldset, NULL);
	 sleep(3);
   return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CNXGI/btsOzOxksag/bO5CqyfHpyuXzm4KfQ2xG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CNXGI/btsOzOxksag/bO5CqyfHpyuXzm4KfQ2xG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CNXGI/btsOzOxksag/bO5CqyfHpyuXzm4KfQ2xG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCNXGI%2FbtsOzOxksag%2FbO5CqyfHpyuXzm4KfQ2xG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;925&quot; height=&quot;388&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;07.mysigaction_intquit.c&lt;/p&gt;
&lt;pre id=&quot;code_1749795288690&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &quot;signalprint.h&quot;   // print_sigset_t()

void handler(int sig) {
    sigset_t sigset;
    // 현재 블록된 시그널 집합을 조회
    sigprocmask(SIG_SETMASK, NULL, &amp;amp;sigset);
    printf(&quot;blocked signal set: &quot;);
    print_sigset_t(&amp;amp;sigset);

    for (int i = 1; i &amp;lt;= 3; i++) {
        printf(&quot;handler_%d for SIGINT\n&quot;, i);
        sleep(1);
    }
}

int main(void) {
    struct sigaction act;
    sigset_t block_set;

    // 1) SIGINT 에만 handler 등록
    sigemptyset(&amp;amp;act.sa_mask);      // handler 중 추가 차단 안 함
    act.sa_handler = handler;
    act.sa_flags   = SA_RESTART;    // 시스템 호출 자동 재시작
    if (sigaction(SIGINT, &amp;amp;act, NULL) &amp;lt; 0) {
        perror(&quot;sigaction(SIGINT)&quot;);
        exit(1);
    }

    // 2) SIGQUIT 은 아무 설정도 하지 않아 기본 동작 유지

    // 3) 그 외 모든 시그널을 block_set 에 추가
    sigfillset(&amp;amp;block_set);         // 집합을 모두 1로
    sigdelset(&amp;amp;block_set, SIGINT);  // SIGINT 만 언블록
    sigdelset(&amp;amp;block_set, SIGQUIT); // SIGQUIT 만 언블록

    // 4) 프로세스 시그널 마스크로 적용 &amp;rarr; 언블록된 시그널만 전달됨
    if (sigprocmask(SIG_SETMASK, &amp;amp;block_set, NULL) &amp;lt; 0) {
        perror(&quot;sigprocmask&quot;);
        exit(1);
    }

    // 5) 메인 루프
    for (int i = 1; ; i++) {
        printf(&quot;signal test --- %d\n&quot;, i);
        sleep(2);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLTk7D/btsOA4ltijL/nDtQtDkOGdKH0jl1R0Hxz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLTk7D/btsOA4ltijL/nDtQtDkOGdKH0jl1R0Hxz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLTk7D/btsOA4ltijL/nDtQtDkOGdKH0jl1R0Hxz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLTk7D%2FbtsOA4ltijL%2FnDtQtDkOGdKH0jl1R0Hxz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;520&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/517</guid>
      <comments>https://hotari.tistory.com/517#entry517comment</comments>
      <pubDate>Fri, 13 Jun 2025 17:05:21 +0900</pubDate>
    </item>
    <item>
      <title>Mini Project1 - No Smoking Area</title>
      <link>https://hotari.tistory.com/516</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project&quot;&gt;SE0NGH0/No_Smoking_Area_Project&lt;/a&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h1&gt;  Smoking Detection System Project&lt;/h1&gt;
&lt;a id=&quot;user-content--smoking-detection-system-project&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-smoking-detection-system-project&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  프로젝트 개요&lt;/h2&gt;
&lt;a id=&quot;user-content--프로젝트-개요&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B0%9C%EC%9A%94&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;본 프로젝트는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;YOLOv5 기반의 흡연자 탐지 시스템&lt;/b&gt;으로,&lt;br /&gt;Flask 서버와 웹캠 스트리밍을 활용하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;금연 구역 내 실시간 흡연 여부를 감지&lt;/b&gt;하고,&lt;br /&gt;로그 및 통계를 자동으로 저장 및 시각화하는 AI 비전 시스템입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  1. 프로젝트 클론&lt;/h2&gt;
&lt;a id=&quot;user-content--1-프로젝트-클론&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-1-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%81%B4%EB%A1%A0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 Git 설치&lt;/h3&gt;
&lt;a id=&quot;user-content-11-git-설치&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#11-git-%EC%84%A4%EC%B9%98&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Windows&lt;/b&gt;:&lt;br /&gt;Git 공식 사이트에서 설치&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Mac/Linux&lt;/b&gt;:&lt;/p&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;mipsasm&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;sudo apt install git    # Ubuntu
brew install git        # Mac&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.2 GitHub에서 프로젝트 클론&lt;/h3&gt;
&lt;a id=&quot;user-content-12-github에서-프로젝트-클론&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#12-github%EC%97%90%EC%84%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%81%B4%EB%A1%A0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;vim&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;git clone https://github.com/yourusername/smoking-detection-system.git
cd smoking-detection-system&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  2. 라이브러리 설치&lt;/h2&gt;
&lt;a id=&quot;user-content--2-라이브러리-설치&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-2-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%84%A4%EC%B9%98&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 가상환경 설정 (선택사항)&lt;/h3&gt;
&lt;a id=&quot;user-content-21-가상환경-설정-선택사항&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#21-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-%EC%84%A0%ED%83%9D%EC%82%AC%ED%95%AD&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;applescript&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;# 가상환경 생성 (Windows)
python -m venv venv

# 가상환경 활성화
venv\Scripts\activate        # Windows
source venv/bin/activate      # Mac/Linux&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 필요 라이브러리 설치&lt;/h3&gt;
&lt;a id=&quot;user-content-22-필요-라이브러리-설치&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#22-%ED%95%84%EC%9A%94-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%84%A4%EC%B9%98&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;cmake&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  3. YOLOv5 모델 다운로드&lt;/h2&gt;
&lt;a id=&quot;user-content--3-yolov5-모델-다운로드&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-3-yolov5-%EB%AA%A8%EB%8D%B8-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 모델 파일 준비&lt;/h3&gt;
&lt;a id=&quot;user-content-31-모델-파일-준비&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#31-%EB%AA%A8%EB%8D%B8-%ED%8C%8C%EC%9D%BC-%EC%A4%80%EB%B9%84&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미&lt;span&gt;&amp;nbsp;&lt;/span&gt;best.pt&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델이 있다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;/models&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더에 복사&lt;/li&gt;
&lt;li&gt;필요 시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0969da;&quot; href=&quot;https://github.com/ultralytics/yolov5&quot;&gt;YOLOv5 GitHub&lt;/a&gt;에서 다운로드 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  4. 웹캠 설정&lt;/h2&gt;
&lt;a id=&quot;user-content--4-웹캠-설정&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-4-%EC%9B%B9%EC%BA%A0-%EC%84%A4%EC%A0%95&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.1 연결 확인&lt;/h3&gt;
&lt;a id=&quot;user-content-41-연결-확인&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#41-%EC%97%B0%EA%B2%B0-%ED%99%95%EC%9D%B8&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Windows: 장치 관리자에서 웹캠 확인&lt;/li&gt;
&lt;li&gt;Linux:&lt;span&gt;&amp;nbsp;&lt;/span&gt;lsusb&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어로 연결 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2 브라우저 접근 허용&lt;/h3&gt;
&lt;a id=&quot;user-content-42-브라우저-접근-허용&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#42-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%A0%91%EA%B7%BC-%ED%97%88%EC%9A%A9&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저에서 카메라 접근 허용 팝업을 수락해야 스트리밍 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  5. 서버 실행&lt;/h2&gt;
&lt;a id=&quot;user-content--5-서버-실행&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-5-%EC%84%9C%EB%B2%84-%EC%8B%A4%ED%96%89&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.1 Flask 서버 실행&lt;/h3&gt;
&lt;a id=&quot;user-content-51-flask-서버-실행&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#51-flask-%EC%84%9C%EB%B2%84-%EC%8B%A4%ED%96%89&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;vim&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;python app.py&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹 브라우저에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0969da;&quot; href=&quot;http://127.0.0.1:5000/&quot;&gt;http://127.0.0.1:5000&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;접속&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  6. 흡연 감지 및 통계&lt;/h2&gt;
&lt;a id=&quot;user-content--6-흡연-감지-및-통계&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-6-%ED%9D%A1%EC%97%B0-%EA%B0%90%EC%A7%80-%EB%B0%8F-%ED%86%B5%EA%B3%84&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.1 감지 기능&lt;/h3&gt;
&lt;a id=&quot;user-content-61-감지-기능&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#61-%EA%B0%90%EC%A7%80-%EA%B8%B0%EB%8A%A5&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실시간 스트리밍 중 흡연자 감지 시 &quot;Stop Smoking Please.&quot; 문구 표시&lt;/li&gt;
&lt;li&gt;감지된 이미지&lt;span&gt;&amp;nbsp;&lt;/span&gt;/smoker&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더에 자동 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.2 통계 시각화&lt;/h3&gt;
&lt;a id=&quot;user-content-62-통계-시각화&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#62-%ED%86%B5%EA%B3%84-%EC%8B%9C%EA%B0%81%ED%99%94&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메인 웹페이지에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;흡연 감지 횟수&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;및 통계 표시&lt;/li&gt;
&lt;li&gt;흡연 발생 시마다 수치 자동 갱신&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  7. 서버 종료&lt;/h2&gt;
&lt;a id=&quot;user-content--7-서버-종료&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-7-%EC%84%9C%EB%B2%84-%EC%A2%85%EB%A3%8C&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;nginx&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;Ctrl + C  # 서버 종료&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  8. 추가 설정 (선택)&lt;/h2&gt;
&lt;a id=&quot;user-content--8-추가-설정-선택&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-8-%EC%B6%94%EA%B0%80-%EC%84%A4%EC%A0%95-%EC%84%A0%ED%83%9D&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1f2328; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;카메라 인덱스 조정&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;cv2.VideoCapture(0)의 인덱스 값을 1 또는 2로 변경해보세요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;YOLOv5 모델 재학습&lt;/b&gt;: 더 나은 성능을 위해 사용자 정의 데이터셋으로 추가 학습 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  프로젝트 폴더 구조&lt;/h2&gt;
&lt;a id=&quot;user-content--프로젝트-폴더-구조&quot; style=&quot;color: #0969da;&quot; href=&quot;https://github.com/SE0NGH0/No_Smoking_Area_Project#-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;background-color: #f6f8fa; color: #1f2328;&quot;&gt;&lt;code&gt;/smoking-detection-system
├── app.py
├── requirements.txt
├── /static
│   ├── /images
│   │   └── police_logo.png
│   └── /css
│       └── style.css
├── /templates
│   └── index.html
└── /models
    └── best.pt (YOLO 모델)
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #59636e; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 프로젝트는 금연 구역에서의 비흡연 환경을 조성하기 위해&lt;br /&gt;실시간 비전 기술을 적용한 사회적 가치 기반 AI 응용 프로젝트입니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝 mini Project</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/516</guid>
      <comments>https://hotari.tistory.com/516#entry516comment</comments>
      <pubDate>Tue, 10 Jun 2025 16:45:08 +0900</pubDate>
    </item>
    <item>
      <title>1일차</title>
      <link>https://hotari.tistory.com/515</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.06.10&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;리눅스 운영&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;U : Router가 Up 인 상태임을 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;G : 경로가 Gateway 임을 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;H : 목적지가 호스트 주소임을 나타냄 D : 경로가 리디렉션에 의해 생성되었음을 나타냄 M : 경로가 리디렉션에 의해 수정되었음을 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 운영체제 구성과 커널&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제 (Operating System)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;windows(&amp;larr; DOS에서부터 시작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Microsoft u 초기에는 cooperative multitasking&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unix&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; AT&amp;amp;T Bell Labs&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; preemptive multitasking&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 저수준의 terminal emulator 개발을 위해서 시작 (Torvalds)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Unix와 호환되는 kernel을 만드는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GNU/Linux&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;316&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ranx6/btsOvvJHKps/kO0qiUBSJkhAPSdhPysUmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ranx6/btsOvvJHKps/kO0qiUBSJkhAPSdhPysUmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ranx6/btsOvvJHKps/kO0qiUBSJkhAPSdhPysUmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRanx6%2FbtsOvvJHKps%2FkO0qiUBSJkhAPSdhPysUmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;316&quot; height=&quot;312&quot; data-origin-width=&quot;316&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 커널&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어 장치 접속 / 연결 (네트워크 장치-어뎁터, 하드디스크, 문자 장치 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개별 프로그램에 메모리 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개별 프로그램에 CPU&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당 프로그램간 정보(데이터) 교환&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vCT85/btsOvaZ7knF/emSjcS0Z5yPzX9vIWBKjsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vCT85/btsOvaZ7knF/emSjcS0Z5yPzX9vIWBKjsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vCT85/btsOvaZ7knF/emSjcS0Z5yPzX9vIWBKjsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvCT85%2FbtsOvaZ7knF%2FemSjcS0Z5yPzX9vIWBKjsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;469&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 유틸리티 프로그램, 라이브러리와 어플리케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유틸리티 프로그램의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 계산기, 달력, 문서편집기, 디스크 관리 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 개발자가 아니더라도, 프로그램 실행시 반드시 필요한 서비스를 제공해주는 것 (libc)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션 (생산성 프로그램)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Web 브라우저 워드 프로세서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 사용자 인터페이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Text-mode User Interface (Command Lineinterface - CLI)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 시스템은 단순히 텍스트 기반의 로그인 프롬프트만 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 일반사용자 ($), 루트 사용자 (#) - 부팅 시 설치 프로그램마다 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 텍스트 기반 문서 편집기 사용 (vi, nano)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graphical User Interface (GUI)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; X window 사용 (Xorg-X11)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; GNOME (Desktop)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; KDE&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 파일시스템 표준 계층구조 (Filesystem Hierarchy Standard, FHS)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Root Filesystem Tree (rootfs)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZtuoh/btsOuNRCcOB/N2c9prfbVPagTNrbkQx1NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZtuoh/btsOuNRCcOB/N2c9prfbVPagTNrbkQx1NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZtuoh/btsOuNRCcOB/N2c9prfbVPagTNrbkQx1NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZtuoh%2FbtsOuNRCcOB%2FN2c9prfbVPagTNrbkQx1NK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;670&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OktZT/btsOvbdB8gc/16saX9oDzGdYdAGd6O9rFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OktZT/btsOvbdB8gc/16saX9oDzGdYdAGd6O9rFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OktZT/btsOvbdB8gc/16saX9oDzGdYdAGd6O9rFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOktZT%2FbtsOvbdB8gc%2F16saX9oDzGdYdAGd6O9rFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;424&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfCnvn/btsOvI95q0a/tKlHfYDt36wNHKxdw4yglk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfCnvn/btsOvI95q0a/tKlHfYDt36wNHKxdw4yglk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfCnvn/btsOvI95q0a/tKlHfYDt36wNHKxdw4yglk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfCnvn%2FbtsOvI95q0a%2FtKlHfYDt36wNHKxdw4yglk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;820&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MGK91/btsOtsgV0rT/v0HpBmWTsZ5R9okS4MOeZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MGK91/btsOtsgV0rT/v0HpBmWTsZ5R9okS4MOeZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MGK91/btsOtsgV0rT/v0HpBmWTsZ5R9okS4MOeZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMGK91%2FbtsOtsgV0rT%2Fv0HpBmWTsZ5R9okS4MOeZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;591&quot; height=&quot;629&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 배포판 (Linux Distributions)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스(커널) 기반의 완전한 운영체제를 만든 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 리눅스 커널 Linux 핵심 툴 세트 (GNU Utilities, X window, disk 관리, 기타 운영에 필요한 기능들)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 보조 프로그램 (Desktop 환경, 생산성 프로그램, 어플리케이션 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 시동 스크립트 (Startup script) (네트워크 프로그램, 로그인 프로그램..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 설치 프로그램 (Installer)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Types of Linux Distributions&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A53jG/btsOu30XrJw/fQHBIOJGx0agu2iASNYSs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A53jG/btsOu30XrJw/fQHBIOJGx0agu2iASNYSs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A53jG/btsOu30XrJw/fQHBIOJGx0agu2iASNYSs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA53jG%2FbtsOu30XrJw%2FfQHBIOJGx0agu2iASNYSs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;422&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pro Developers&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be180L/btsOu91dyHX/VqHsaYNMKKHzXKWRPP3vp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be180L/btsOu91dyHX/VqHsaYNMKKHzXKWRPP3vp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be180L/btsOu91dyHX/VqHsaYNMKKHzXKWRPP3vp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe180L%2FbtsOu91dyHX%2FVqHsaYNMKKHzXKWRPP3vp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;302&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Market Share&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cshNah/btsOuiY6SPi/qkExH4nkEBdQnD3BphkSH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cshNah/btsOuiY6SPi/qkExH4nkEBdQnD3BphkSH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cshNah/btsOuiY6SPi/qkExH4nkEBdQnD3BphkSH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcshNah%2FbtsOuiY6SPi%2FqkExH4nkEBdQnD3BphkSH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;572&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu 배포 주기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XBNbl/btsOuIpeVkb/nJ7ZXe3WWDZWBIkYWKVdkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XBNbl/btsOuIpeVkb/nJ7ZXe3WWDZWBIkYWKVdkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XBNbl/btsOuIpeVkb/nJ7ZXe3WWDZWBIkYWKVdkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXBNbl%2FbtsOuIpeVkb%2FnJ7ZXe3WWDZWBIkYWKVdkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;215&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 Linux 배포판을 선택할 것인가?&lt;/p&gt;
&lt;table id=&quot;1ffc5962-3e61-8021-a502-cbd4da1a9a36&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr id=&quot;1ffc5962-3e61-8048-86a7-e33770eba41b&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;배포판&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;선택 기준 (제안)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-80c1-b024-f640c9d2ee6d&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;RedHat Enterprise Linux (RHEL)&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;기술지원 계약이 필요한 경우&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-800b-a0f2-d50dd3ec288e&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;CentOS&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;기술지원 계약 없이 기업용 RHEL을 사용하고 싶을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-80ad-9a95-ec0943de6c55&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;Fedora&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;랩탑이나 데스크탑에 RHEL 개발 환경을 설치하고자 할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8023-b425-fd4c2437afbf&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;Linux Mint&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;영화보기, 음악듣기, 게임 용으로 그래픽 환경에서의 개인적 데스크 탑을 원할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8065-b792-cd6e75262bd1&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;Debian&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;서버, 랩탑 또는 주로 디바이스에서 사용하고자 할 때 (RaspberryPi)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-80f7-b628-f19c21c74669&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;Ubuntu&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;Debian 기반의 Desktop 버전을 사용하고자 할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8040-a477-ed89ea022afe&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;Kali Linux&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;한번의 클릭으로 해킹을 하기를 원할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-801e-a7ed-d237637ced3d&quot;&gt;
&lt;td id=&quot;JfZ\&quot;&gt;기타&lt;/td&gt;
&lt;td id=&quot;@==U&quot;&gt;고급 사용자들은 Arch, Gentoo. OpenSUSE,,, 등을 사용할 수도&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉘과 파일시스템 기본 이해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉘(shell)이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Shell은 사용자가 입력한 모든 명령어를 읽어서 해석한 후 운영체제에 전달하여 실행을 요청하는 응용 프로그램&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 쉘 스크립트에서는 명령어 해석기(Command Interpreter) 라고 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 터미널(키보드와 모니터)을 연결하고 터미널을 통하여 입출력을 제어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 리눅스 시스템과 사용자를 연결하는 통로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 리눅스 운영체제와 리눅스 사용자 간의 저수준 인터페이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉘(Shell)의 주요 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 운영체제와 키보드 인터페이스로서의 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 사용자 편의에 맞게 명령어를 만들고 변경 및 추가하는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 새 명령어 개발을 위한 컴퓨터 언어로서의 기능 - 쉘 스크립트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉡의 종류&lt;/p&gt;
&lt;table id=&quot;1ffc5962-3e61-80f1-96c5-cdfb6812d623&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr id=&quot;1ffc5962-3e61-800b-9e56-eff756d32573&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;쉘(shell)의 종류&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;특징&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;프롬프트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-80ff-b6b3-d57061e7acd1&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;bash Bourne Again shell&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;Bourne again shell은 최초로 개발된 쉘인 Bourne shell의 변종임.&lt;br /&gt;리눅스에서 가장 많이 사용되는 IEEE POSIX 호환이며 Borune shell과 호환되는 쉘로서 GNU 프로젝트에 의해 만들어지고 배포되고 있음.&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-80b9-9b54-cba0b162de24&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;sh Bourne shell&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;Bourne 쉘은 C쉘이나 Korn 쉘과 기능적인 면을 비교해 보면 미흡한 점이 있는데, 그 중 가장 큰 단점은 상호 대화형(Interactive) 방식을 취하고 있지 않다는 점임.&lt;br /&gt;Steven Bourne의 Bourne shell, sh&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8035-9f6a-f82da592b0af&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;csh C-Program Style shell&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;버클리 캘리포니아 대학에서 개발된 프로그래머들에게 적합한 shell임. 대화형 사용법에서는 Bourne shell과 대부분 호환되지만 전혀 다른 프로그래밍 인터페이스를 가지고 있음.&lt;br /&gt;Bill Joy의 C shell, csh &lt;br /&gt;C언어와 유사한 언어를 사용, 상호 대화형 방식으로 구성&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8020-8ebf-d76fc026ef76&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;ksh Korn shell&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;일반적으로 유닉스에서 가장 많이 사용되고 있는 shell이며 Bourne shell에 처음으로 현대적인 shell 기능(C shell로부터 차용한 것임)을 도입한 shell임. Bourne shell과 호환됨.&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1ffc5962-3e61-8090-8a68-e8453fb922cf&quot;&gt;
&lt;td id=&quot;ktre&quot;&gt;zsh&lt;/td&gt;
&lt;td id=&quot;aQIT&quot;&gt;Korn shell과 매우 유사한 셸이지만 Korn shell보다 더 많고 유용한 기능 등을 추가하여 개선시킨 것임.&lt;/td&gt;
&lt;td id=&quot;[m&amp;#96;v&quot;&gt;%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 시스템 표준 계층 (FHS)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 시스템(file system)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 컴퓨터에서 파일이나 자료를 쉽게 발견 및 접근할 수 있도록 보관 또는 조직하는 체제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 어플리케이션이 사용하는 파일과 미디어에 저장된 데이터 사이를 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 시스템 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 저장된 데이터에 접근하는 것을 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 데이터를 보관하고 접근하는 시간을 개선하기 위하여 파일시스템을 튜닝하고, 모니터링하며, 복구하는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 시스템 탐험하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFxw02/btsOveuE2QO/XeLIjvIoTzO1R4wm0RefTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFxw02/btsOveuE2QO/XeLIjvIoTzO1R4wm0RefTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFxw02/btsOveuE2QO/XeLIjvIoTzO1R4wm0RefTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFxw02%2FbtsOveuE2QO%2FXeLIjvIoTzO1R4wm0RefTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;192&quot; height=&quot;439&quot; data-origin-width=&quot;192&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 작업 디렉터리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pwd : Print current working directory&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 처음 로그인을 하면 항상 사용자의 home 디렉토리가 기본 working directory가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자의 기본 working directory는 사용자가 생성될 때 결정되며 /etc/passwd 파일에 해당 정보가 기록되어 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cokQti/btsOuDO2EgG/SKWAkdL1q2YP7UyT8xigMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cokQti/btsOuDO2EgG/SKWAkdL1q2YP7UyT8xigMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cokQti/btsOuDO2EgG/SKWAkdL1q2YP7UyT8xigMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcokQti%2FbtsOuDO2EgG%2FSKWAkdL1q2YP7UyT8xigMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;478&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Home Directory로 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; cd , cd ~, pushd, popd&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9r6pA/btsOvyfmQdO/rTN5UCE4wtVfHA3OtzD8G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9r6pA/btsOvyfmQdO/rTN5UCE4wtVfHA3OtzD8G0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9r6pA/btsOvyfmQdO/rTN5UCE4wtVfHA3OtzD8G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9r6pA%2FbtsOvyfmQdO%2FrTN5UCE4wtVfHA3OtzD8G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;342&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; Parent Directory로 이동 : cd ..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 이전 디렉토리로 이동 : cd -&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duFFDu/btsOtvxWy6Q/iVAYLq48fax8OyrqyO69k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duFFDu/btsOtvxWy6Q/iVAYLq48fax8OyrqyO69k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duFFDu/btsOtvxWy6Q/iVAYLq48fax8OyrqyO69k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduFFDu%2FbtsOtvxWy6Q%2FiVAYLq48fax8OyrqyO69k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;194&quot; height=&quot;535&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절대 경로(absolute path)와 상대 경로(relative path)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절대경로 : &quot;/&quot;로 시작하는 경로 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대경로 : &quot;/&quot;로 시작하지 않는 경로는 현재 위치(pwd)를 기준으로 동작함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kw27G/btsOt5yMAkb/Fwj7TjkX7LjRcWMsAKmx20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kw27G/btsOt5yMAkb/Fwj7TjkX7LjRcWMsAKmx20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kw27G/btsOt5yMAkb/Fwj7TjkX7LjRcWMsAKmx20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkw27G%2FbtsOt5yMAkb%2FFwj7TjkX7LjRcWMsAKmx20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;265&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory 목록 (내용) 보기 ls&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory 내의 숨겨진 파일 보기 ls -a&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory 내용 자세하게 보기 (파일의 퍼미션, 소유자, 생성 날짜, 크기 등 ) ls -l&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory 내의 파일의 유형 정보 보기 ls -F&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory 하위 디렉토리를 이동하며 반복적으로 디렉토리 내용 보기 (Recursive) ls -R&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 내용 보기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; cat /etc/hosts&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 파일의 내용을 터미널(표준출력 장치)에 출력함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 단위로 파일 내용 보기 less /etc/passwd&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;more : 페이지 단위로 파일 내용 보기 more /etc/passwd&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;head : 파일의 시작에서부터 지정한 줄 수만큼 내용 보기 (초기 기본 설정값은 10줄)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tail : 파일의 끝에서부터 지정한 줄 수만큼 내용 보기 (초기 기본 설정값은 10줄)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 임베디드 리눅스</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/515</guid>
      <comments>https://hotari.tistory.com/515#entry515comment</comments>
      <pubDate>Tue, 10 Jun 2025 16:44:59 +0900</pubDate>
    </item>
    <item>
      <title>11일차</title>
      <link>https://hotari.tistory.com/514</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.30&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uart.c&lt;/p&gt;
&lt;pre id=&quot;code_1748571528425&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;
#include &amp;lt;wiringSerial.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;termios.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#define B_RATE B9600

int fd;  // Serial file descriptor

void* ReadProcess(void* arg)
{
    char buf[1024];
    while (1)
    {
        int n = serialDataAvail(fd);
        if (n &amp;gt; 0 &amp;amp;&amp;amp; n &amp;lt; sizeof(buf))
        {
            for (int i = 0; i &amp;lt; n; i++)
            {
                char ch = serialGetchar(fd);

                // 줄바꿈 문자 무시 (선택 사항)
                if (ch == '\n' || ch == '\r') {
                    continue;
                }

                buf[i] = ch;
                buf[i + 1] = '\0';  // 실시간 null-terminate
                printf(&quot;&amp;lt;&amp;lt; %s\n&quot;, buf);  // 수신 데이터 출력
                fflush(stdout);
            }
        }
        delay(10);  // CPU 사용 제한
    }
    return NULL;
}

int main()
{
    if (wiringPiSetup() == -1) {
        fprintf(stderr, &quot;wiringPi setup failed\n&quot;);
        exit(1);
    }

    fd = serialOpen(&quot;/dev/serial0&quot;, 9600);
    if (fd &amp;lt; 0) {
        perror(&quot;serialOpen failed&quot;);
        exit(1);
    }

    pthread_t rp;
    if (pthread_create(&amp;amp;rp, NULL, ReadProcess, NULL) != 0) {
        fprintf(stderr, &quot;pthread_create failed\n&quot;);
        exit(1);
    }

    char buf[500];
    while (1)
    {
        printf(&quot;&amp;gt;&amp;gt; &quot;);
        fflush(stdout);
        if (fgets(buf, sizeof(buf), stdin) != NULL) {
            // 개행 문자 제거
            char *newline = strchr(buf, '\n');
            if (newline) *newline = '\0';

            // 시리얼로 전송
            serialPuts(fd, buf);
            serialPutchar(fd, '\n');  // 필요 시 줄바꿈 명시적으로 추가
        }
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/514</guid>
      <comments>https://hotari.tistory.com/514#entry514comment</comments>
      <pubDate>Wed, 4 Jun 2025 10:32:09 +0900</pubDate>
    </item>
    <item>
      <title>10일차</title>
      <link>https://hotari.tistory.com/513</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.29&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7vVeY/btsOhKgyHjY/dWUf8OT4ftSt3QKyvtDsVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7vVeY/btsOhKgyHjY/dWUf8OT4ftSt3QKyvtDsVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7vVeY/btsOhKgyHjY/dWUf8OT4ftSt3QKyvtDsVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7vVeY%2FbtsOhKgyHjY%2FdWUf8OT4ftSt3QKyvtDsVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;401&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ogKP1/btsOf8v1zfX/otA5Igs8cbYiwrbVEdfV6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ogKP1/btsOf8v1zfX/otA5Igs8cbYiwrbVEdfV6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ogKP1/btsOf8v1zfX/otA5Igs8cbYiwrbVEdfV6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FogKP1%2FbtsOf8v1zfX%2FotA5Igs8cbYiwrbVEdfV6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;407&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dg3y8L/btsOhFfluk0/Xxo7wYQtFyd4BFWRUHdUWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dg3y8L/btsOhFfluk0/Xxo7wYQtFyd4BFWRUHdUWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dg3y8L/btsOhFfluk0/Xxo7wYQtFyd4BFWRUHdUWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg3y8L%2FbtsOhFfluk0%2FXxo7wYQtFyd4BFWRUHdUWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;370&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l2M76/btsOfNMvp6l/DP3Xv7U6BnBdfEfY2JAAS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l2M76/btsOfNMvp6l/DP3Xv7U6BnBdfEfY2JAAS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l2M76/btsOfNMvp6l/DP3Xv7U6BnBdfEfY2JAAS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl2M76%2FbtsOfNMvp6l%2FDP3Xv7U6BnBdfEfY2JAAS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;385&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6y4Uh/btsOg9OugcI/DKx888TOTOrye9K7OxJAO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6y4Uh/btsOg9OugcI/DKx888TOTOrye9K7OxJAO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6y4Uh/btsOg9OugcI/DKx888TOTOrye9K7OxJAO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6y4Uh%2FbtsOg9OugcI%2FDKx888TOTOrye9K7OxJAO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;423&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqkyGW/btsOhVCe2O8/T2VcIt6CG6tg0WyEKiiMDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqkyGW/btsOhVCe2O8/T2VcIt6CG6tg0WyEKiiMDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqkyGW/btsOhVCe2O8/T2VcIt6CG6tg0WyEKiiMDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqkyGW%2FbtsOhVCe2O8%2FT2VcIt6CG6tg0WyEKiiMDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;427&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xojvr/btsOg0xxOyk/UgC27UNC5tYUBCfiMHxBf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xojvr/btsOg0xxOyk/UgC27UNC5tYUBCfiMHxBf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xojvr/btsOg0xxOyk/UgC27UNC5tYUBCfiMHxBf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXojvr%2FbtsOg0xxOyk%2FUgC27UNC5tYUBCfiMHxBf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;385&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Cjz0/btsOhXGNNyq/AKwYmKCtH739OvNcbpik21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Cjz0/btsOhXGNNyq/AKwYmKCtH739OvNcbpik21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Cjz0/btsOhXGNNyq/AKwYmKCtH739OvNcbpik21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Cjz0%2FbtsOhXGNNyq%2FAKwYmKCtH739OvNcbpik21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;383&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wy3Tv/btsOieBxpwv/A17cXDhtDeSYSbtw3entu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wy3Tv/btsOieBxpwv/A17cXDhtDeSYSbtw3entu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wy3Tv/btsOieBxpwv/A17cXDhtDeSYSbtw3entu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWy3Tv%2FbtsOieBxpwv%2FA17cXDhtDeSYSbtw3entu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;261&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tTClN/btsOgJJvNIx/aCFlLcJgvCZDB5vXYFqU80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tTClN/btsOgJJvNIx/aCFlLcJgvCZDB5vXYFqU80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tTClN/btsOgJJvNIx/aCFlLcJgvCZDB5vXYFqU80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtTClN%2FbtsOgJJvNIx%2FaCFlLcJgvCZDB5vXYFqU80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;382&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tpt0I/btsOgMztGTi/pw9XAFqsZBi8wm9ng602Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tpt0I/btsOgMztGTi/pw9XAFqsZBi8wm9ng602Fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tpt0I/btsOgMztGTi/pw9XAFqsZBi8wm9ng602Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftpt0I%2FbtsOgMztGTi%2Fpw9XAFqsZBi8wm9ng602Fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;299&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKPznz/btsOipbUD7L/PoohRK8u9j2U3aei9qINDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKPznz/btsOipbUD7L/PoohRK8u9j2U3aei9qINDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKPznz/btsOipbUD7L/PoohRK8u9j2U3aei9qINDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKPznz%2FbtsOipbUD7L%2FPoohRK8u9j2U3aei9qINDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;631&quot; height=&quot;222&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sercer.c&lt;/p&gt;
&lt;pre id=&quot;code_1748488496059&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// server.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;signal.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

#define PORT 9000

static void kill_port_users(int port) {
    char cmd[64];
    snprintf(cmd, sizeof(cmd), &quot;fuser -k %d/tcp 2&amp;gt;/dev/null&quot;, port);
    system(cmd);
}

int main(void) {
    int server_sock, client_sock;
    struct sockaddr_in saddr, caddr;
    socklen_t addr_len = sizeof(caddr);
    char buf[1024];
    ssize_t r;
    int opt = 1;

    // 기존 포트 점유 프로세스 제거
    kill_port_users(PORT);

    // 1) socket()
    if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) &amp;lt; 0) {
        perror(&quot;socket&quot;);
        return 1;
    }

    // 2) SO_REUSEADDR
    if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &amp;amp;opt, sizeof(opt)) &amp;lt; 0) {
        perror(&quot;setsockopt&quot;);
        close(server_sock);
        return 1;
    }

    // 3) bind()
    memset(&amp;amp;saddr, 0, sizeof(saddr));
    saddr.sin_family      = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port        = htons(PORT);
    if (bind(server_sock, (struct sockaddr*)&amp;amp;saddr, sizeof(saddr)) &amp;lt; 0) {
        perror(&quot;bind&quot;);
        close(server_sock);
        return 1;
    }

    // 4) listen()
    if (listen(server_sock, 2) &amp;lt; 0) {
        perror(&quot;listen&quot;);
        close(server_sock);
        return 1;
    }
    printf(&quot;▶ Server listening on port %d &amp;hellip;\n&quot;, PORT);

    // 5) accept()
    if ((client_sock = accept(server_sock, (struct sockaddr*)&amp;amp;caddr, &amp;amp;addr_len)) &amp;lt; 0) {
        perror(&quot;accept&quot;);
        close(server_sock);
        return 1;
    }

    // 6) 원격 엔드포인트 정보 출력
    printf(&quot;▶ Client connected!\n&quot;);
    printf(&quot;   RemoteEP_ADDR  = %s\n&quot;, inet_ntoa(caddr.sin_addr));
    printf(&quot;   RemoteEP_port  = %d\n&quot;, ntohs(caddr.sin_port));

    // 7) read loop
    while ((r = read(client_sock, buf, sizeof(buf)-1)) &amp;gt; 0) {
        buf[r] = '\0';
        printf(&quot;&amp;gt; %s (%zd bytes)\n&quot;, buf, r);
    }
    if (r &amp;lt; 0) perror(&quot;read&quot;);

    close(client_sock);
    close(server_sock);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;client.c&lt;/p&gt;
&lt;pre id=&quot;code_1748488508061&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// client.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;

#define PORT 9000

int main(int argc, char *argv[]) {
    int sock;
    struct sockaddr_in saddr;
    char buf[500];
    ssize_t w;

    if (argc != 2) {
        fprintf(stderr, &quot;Usage: %s &amp;lt;server_ip&amp;gt;\n&quot;, argv[0]);
        return 1;
    }
    const char *server_ip = argv[1];

    // 1) 소켓 생성
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) &amp;lt; 0) {
        perror(&quot;socket&quot;);
        return 1;
    }

    // 2) 서버 주소 세팅
    memset(&amp;amp;saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port   = htons(PORT);
    if (inet_aton(server_ip, &amp;amp;saddr.sin_addr) == 0) {
        fprintf(stderr, &quot;Invalid IP address: %s\n&quot;, server_ip);
        close(sock);
        return 1;
    }

    // 3) 서버에 연결
    if (connect(sock, (struct sockaddr *)&amp;amp;saddr, sizeof(saddr)) &amp;lt; 0) {
        perror(&quot;connect&quot;);
        close(sock);
        return 1;
    }

    // 4) 연결 정보 출력
    printf(&quot;▶ Connected to %s:%d\n&quot;, server_ip, PORT);
    printf(&quot;   Server_ADDR  = %s\n&quot;, inet_ntoa(saddr.sin_addr));
    printf(&quot;   Server_PORT  = %d\n&quot;, ntohs(saddr.sin_port));

    // 5) stdin에서 한 줄씩 읽어서 서버로 전송 (&amp;ldquo;&amp;gt; &amp;rdquo; 프롬프트 추가)
    while (1) {
        printf(&quot;&amp;gt; &quot;);              // 프롬프트
        fflush(stdout);            // 바로 출력되도록 플러시

        if (!fgets(buf, sizeof(buf), stdin))
            break;                 // EOF 또는 에러 시 종료

        size_t len = strlen(buf);
        if (len &amp;gt; 0 &amp;amp;&amp;amp; buf[len-1] == '\n')
            buf[len-1] = '\0';     // 개행 제거
        if (buf[0] == '\0')
            continue;              // 빈 줄은 건너뛰기

        w = write(sock, buf, strlen(buf));
        if (w &amp;lt; 0) {
            perror(&quot;write&quot;);
            break;
        }
    }

    close(sock);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ELuJe/btsOhepHs7E/krU9E8y8BsYac9jYI7Smk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ELuJe/btsOhepHs7E/krU9E8y8BsYac9jYI7Smk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ELuJe/btsOhepHs7E/krU9E8y8BsYac9jYI7Smk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FELuJe%2FbtsOhepHs7E%2FkrU9E8y8BsYac9jYI7Smk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;458&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/513</guid>
      <comments>https://hotari.tistory.com/513#entry513comment</comments>
      <pubDate>Thu, 29 May 2025 18:38:15 +0900</pubDate>
    </item>
    <item>
      <title>9일차</title>
      <link>https://hotari.tistory.com/512</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.28&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초음파센서 동작&lt;/p&gt;
&lt;pre id=&quot;code_1748403016528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;

#define TRIG 27
#define ECHO 28

void setup() {
    wiringPiSetup();
    pinMode(TRIG, OUTPUT);
    pinMode(ECHO, INPUT);
    digitalWrite(TRIG, LOW);
    delay(30);  // 센서 안정화 대기
}

double getDistance() {
    // Trigger pulse
    digitalWrite(TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG, LOW);

    // Echo 신호가 HIGH가 될 때까지 대기
    while (digitalRead(ECHO) == LOW);

    int startTime = micros();

    // Echo 신호가 LOW가 될 때까지 대기
    while (digitalRead(ECHO) == HIGH);

    int endTime = micros();

    // 거리 계산: 왕복 시간 x 음속(0.017 cm/us)
    double distance = (endTime - startTime) * 0.017;
    return distance;
}

int main() {
    setup();

    while (1) {
        double distance = getDistance();
        printf(&quot;Distance: %.2f cm\n&quot;, distance);
        delay(500);  // 0.5초 간격
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서보모터와 초음파센서 연동&lt;/p&gt;
&lt;pre id=&quot;code_1748403037224&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;
#include &amp;lt;softPwm.h&amp;gt;

#define TRIG 27
#define ECHO 28
#define SERVO_PIN 29
#define PWM_RANGE 200

// 각도를 소프트 PWM duty로 변환 (0도:5 ~ 180도:25)
int angleToDuty(int angle) {
    return (5 * (180 - angle) + 25 * angle) / 180;
}

// 거리 측정 함수
double getDistance() {
    digitalWrite(TRIG, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG, LOW);

    while (digitalRead(ECHO) == LOW);
    int startTime = micros();

    while (digitalRead(ECHO) == HIGH);
    int endTime = micros();

    return (endTime - startTime) * 0.017;  // cm
}

// 초기화
int setup() {
    if (wiringPiSetup() == -1) return 1;

    pinMode(TRIG, OUTPUT);
    pinMode(ECHO, INPUT);
    digitalWrite(TRIG, LOW);
    delay(30);

    if (softPwmCreate(SERVO_PIN, 0, PWM_RANGE) != 0) {
        fprintf(stderr, &quot;softPwmCreate failed\n&quot;);
        return 1;
    }

    return 0;
}

int main() {
    if (setup() != 0) return 1;

    while (1) {
        double distance = getDistance();
        printf(&quot;Distance: %.2f cm\n&quot;, distance);

        if (distance &amp;lt; 10.0) {
            // 역회전: 180&amp;deg; &amp;rarr; 0&amp;deg;
            for (int ang = 180; ang &amp;gt;= 0; ang -= 5) {
                softPwmWrite(SERVO_PIN, angleToDuty(ang));
                delay(20);
            }
        } else {
            // 정회전: 0&amp;deg; &amp;rarr; 180&amp;deg;
            for (int ang = 0; ang &amp;lt;= 180; ang += 5) {
                softPwmWrite(SERVO_PIN, angleToDuty(ang));
                delay(20);
            }
        }

        delay(500);  // 다음 측정까지 대기
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스텝모터와 초음파센서 연동&lt;/p&gt;
&lt;pre id=&quot;code_1748407698458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;

// 초음파 센서 핀 (wiringPi 번호)
#define TRIG    27
#define ECHO    28

// 스텝모터 핀 (wiringPi 번호)
#define ORANGE  21
#define YELLOW  22
#define PINK    23
#define BLUE    24
#define RED     25  // 모터 전원용

// 초음파 거리 측정 함수 (cm)
double get_distance() {
    digitalWrite(TRIG, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG, LOW);

    // Echo 신호 시작 대기
    while (digitalRead(ECHO) == LOW);
    long start_time = micros();
    // Echo 신호 끝 대기
    while (digitalRead(ECHO) == HIGH);
    long end_time = micros();

    // 거리 계산: 왕복 시간(us) &amp;times; 음속(cm/us) / 2
    return (end_time - start_time) * 0.017;
}

// Full-step 모드 한 스텝 구동
void step_full(int step) {
    switch(step) {
        case 0:
            digitalWrite(ORANGE, HIGH);
            digitalWrite(YELLOW, HIGH);
            digitalWrite(PINK,   LOW);
            digitalWrite(BLUE,   LOW);
            break;
        case 1:
            digitalWrite(ORANGE, LOW);
            digitalWrite(YELLOW, HIGH);
            digitalWrite(PINK,   HIGH);
            digitalWrite(BLUE,   LOW);
            break;
        case 2:
            digitalWrite(ORANGE, LOW);
            digitalWrite(YELLOW, LOW);
            digitalWrite(PINK,   HIGH);
            digitalWrite(BLUE,   HIGH);
            break;
        case 3:
            digitalWrite(ORANGE, HIGH);
            digitalWrite(YELLOW, LOW);
            digitalWrite(PINK,   LOW);
            digitalWrite(BLUE,   HIGH);
            break;
        default:
            break;
    }
}

int main() {
    // wiringPi 초기화
    if (wiringPiSetup() == -1) {
        fprintf(stderr, &quot;wiringPi setup failed\n&quot;);
        return 1;
    }

    // 핀 모드 설정
    pinMode(TRIG, OUTPUT);
    pinMode(ECHO, INPUT);
    pinMode(ORANGE, OUTPUT);
    pinMode(YELLOW, OUTPUT);
    pinMode(PINK, OUTPUT);
    pinMode(BLUE, OUTPUT);
    pinMode(RED, OUTPUT);

    // 모터 전원 공급
    digitalWrite(RED, HIGH);

    while (1) {
        double distance = get_distance();
        printf(&quot;Distance: %.2f cm\n&quot;, distance);

        if (distance &amp;lt; 10.0) {
            // 역회전: 역방향 인덱스 보정 적용
            for (int i = 0; i &amp;lt; 512; i++) {
                int idx = (3 - (i % 4) + 4) % 4;
                step_full(idx);
                delay(5);
            }
        } else {
            // 정회전
            for (int i = 0; i &amp;lt; 512; i++) {
                step_full(i % 4);
                delay(5);
            }
        }

        delay(1000);  // 1초 대기 후 다음 측정
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/512</guid>
      <comments>https://hotari.tistory.com/512#entry512comment</comments>
      <pubDate>Wed, 28 May 2025 17:51:41 +0900</pubDate>
    </item>
    <item>
      <title>8일차</title>
      <link>https://hotari.tistory.com/511</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.27&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LJMVl/btsOeE1r9IP/af6xLdSjacRBzHejvI4kjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LJMVl/btsOeE1r9IP/af6xLdSjacRBzHejvI4kjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LJMVl/btsOeE1r9IP/af6xLdSjacRBzHejvI4kjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLJMVl%2FbtsOeE1r9IP%2Faf6xLdSjacRBzHejvI4kjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;425&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csV5jb/btsOd6c7QfZ/1fEG3mQR4PDGg8SyFWe7SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csV5jb/btsOd6c7QfZ/1fEG3mQR4PDGg8SyFWe7SK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csV5jb/btsOd6c7QfZ/1fEG3mQR4PDGg8SyFWe7SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsV5jb%2FbtsOd6c7QfZ%2F1fEG3mQR4PDGg8SyFWe7SK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;455&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SNPRr/btsOcUq0Lic/kA1EfGSa2X6skUtiJGckI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SNPRr/btsOcUq0Lic/kA1EfGSa2X6skUtiJGckI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SNPRr/btsOcUq0Lic/kA1EfGSa2X6skUtiJGckI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSNPRr%2FbtsOcUq0Lic%2FkA1EfGSa2X6skUtiJGckI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;616&quot; height=&quot;483&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스텝 모터 동작&lt;/p&gt;
&lt;pre id=&quot;code_1748314203473&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;

#define ORANGE  21
#define YELLOW  22
#define PINK    23
#define BLUE    24 
#define RED     25

void step_wave(int step)
{   
   switch(step)
   { 
      case 0:
         digitalWrite(ORANGE,1);
         digitalWrite(YELLOW,0);
         digitalWrite(PINK,0);
         digitalWrite(BLUE,0);
         break;
      case 1:
         digitalWrite(ORANGE,0);
         digitalWrite(YELLOW,1);
         digitalWrite(PINK,0);
         digitalWrite(BLUE,0);
         break;
      case 2:
         digitalWrite(ORANGE,0);
         digitalWrite(YELLOW,0);
         digitalWrite(PINK,1);
         digitalWrite(BLUE,0);
         break;
      case 3:
         digitalWrite(ORANGE,0);
         digitalWrite(YELLOW,0);
         digitalWrite(PINK,0);
         digitalWrite(BLUE,1);
         break;
      default:
         break;
   }
}

int main()
{   
   wiringPiSetup();
   pinMode(ORANGE,OUTPUT);
   pinMode(YELLOW,OUTPUT);
   pinMode(PINK,OUTPUT);
   pinMode(BLUE,OUTPUT);
   pinMode(RED ,OUTPUT);  //power line 
   digitalWrite(7,1);
   
   for(int i=0;i&amp;lt;2048;i++) //half or full(wave)
   { 
      step_wave(i%4); //0 1 2 3 0 1 2 3 
      delay(5);
    }
   return(1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bApXcF/btsOemteTHf/KQr3ofdisWxgnYarLKsBd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bApXcF/btsOemteTHf/KQr3ofdisWxgnYarLKsBd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bApXcF/btsOemteTHf/KQr3ofdisWxgnYarLKsBd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbApXcF%2FbtsOemteTHf%2FKQr3ofdisWxgnYarLKsBd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;93&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748327753526&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;

#define ORANGE  21 // 29 (물리적 pin 번호)
#define YELLOW  22 // 31
#define PINK    23 // 33
#define BLUE    24 // 35
#define RED     25 // 37 임시 전원용 : 사용 불가가
#define GND     39 // 39 참고용

void step_wave(int step)
{   
   switch(step)
   { 
      case 0:
        digitalWrite(ORANGE, 1);
        digitalWrite(YELLOW, 0);
        digitalWrite(PINK, 0);
        digitalWrite(BLUE, 0);
        break;
      case 1:
        digitalWrite(ORANGE, 0);
        digitalWrite(YELLOW, 1);
        digitalWrite(PINK, 0);
        digitalWrite(BLUE, 0);
        break;
      case 2:
        digitalWrite(ORANGE, 0);
        digitalWrite(YELLOW, 0);
        digitalWrite(PINK, 1);
        digitalWrite(BLUE, 0);
        break;
      case 3:
        digitalWrite(ORANGE, 0);
        digitalWrite(YELLOW, 0);
        digitalWrite(PINK, 0);
        digitalWrite(BLUE, 1);
        break;
      default:
        break;
   }
}

void step_full(int step)
{
   switch(step)
   {
      case 0: // Coil 1 + Coil 2
	  	digitalWrite(ORANGE, HIGH);
        digitalWrite(YELLOW, HIGH);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   LOW);
        break;
      case 1: // Coil 2 + Coil 3
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, HIGH);
        digitalWrite(PINK,   HIGH);
        digitalWrite(BLUE,   LOW);
        break;
      case 2: // Coil 3 + Coil 4
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   HIGH);
        digitalWrite(BLUE,   HIGH);
        break;
      case 3: // Coil 4 + Coil 1
        digitalWrite(ORANGE, HIGH);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   HIGH);
        break;
      default:
        break;
   }
}

void step_half(int step)
{
   switch(step)
   {
      case 0: // Coil 1 only
	  	digitalWrite(ORANGE, HIGH);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   LOW);
        break;
      case 1: // Coil 1 + Coil 2
        digitalWrite(ORANGE, HIGH);
        digitalWrite(YELLOW, HIGH);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   LOW);
        break;
      case 2: // Coil 2 only
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, HIGH);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   LOW);
        break;
      case 3: // Coil 2 + Coil 3
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, HIGH);
        digitalWrite(PINK,   HIGH);
        digitalWrite(BLUE,   LOW);
        break;
      case 4: // Coil 3 only
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   HIGH);
        digitalWrite(BLUE,   LOW);
        break;
      case 5: // Coil 3 + Coil 4
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   HIGH);
        digitalWrite(BLUE,   HIGH);
        break;
      case 6: // Coil 4 only
        digitalWrite(ORANGE, LOW);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   HIGH);
        break;
      case 7: // Coil 4 + Coil 1
        digitalWrite(ORANGE, HIGH);
        digitalWrite(YELLOW, LOW);
        digitalWrite(PINK,   LOW);
        digitalWrite(BLUE,   HIGH);
        break;
      default:
        break;
   }
}

int main()
{   
   wiringPiSetup();
   pinMode(ORANGE, OUTPUT);
   pinMode(YELLOW, OUTPUT);
   pinMode(PINK, OUTPUT);
   pinMode(BLUE, OUTPUT);
   pinMode(RED , OUTPUT);  //power line 
   digitalWrite(RED,HIGH);
   
   for(int i=0; i &amp;lt; 4096; i++) //half or full(wave)
   {
		// Wave drive
		//step_wave(i % 4);
		//delay(5);
		// Full drive
		step_full(i % 4);
		delay(5);
		// Half-drive
		//step_half(i % 8);
		//delay(5);
   }
   return(1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서보 모터 동작&lt;/p&gt;
&lt;pre id=&quot;code_1748332563348&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;wiringPi.h&amp;gt;
#include &amp;lt;softPwm.h&amp;gt;

#define SERVO_PIN 29   // wiringPi 번호 21 &amp;rarr; 물리적 핀 29 (BCM 5)
#define PWM_RANGE 200 // 소프트 PWM 분해능 (0&amp;ndash;200)

// 서보 펄스 폭(duty)을 각도로 변환: 0&amp;deg; &amp;rarr; 5, 90&amp;deg; &amp;rarr; 15, 180&amp;deg; &amp;rarr; 25 정도
int angleToDuty(int angle) {
    return (5 * (180 - angle) + 25 * angle) / 180;
}

int main(void) {
    // wiringPi 초기화
    if (wiringPiSetup() == -1) {
        fprintf(stderr, &quot;wiringPi setup failed\n&quot;);
        return 1;
    }

    // SERVO_PIN에 소프트 PWM 설정 (초기값 0, 범위 PWM_RANGE)
    if (softPwmCreate(SERVO_PIN, 0, PWM_RANGE) != 0) {
        fprintf(stderr, &quot;softPwmCreate failed\n&quot;);
        return 1;
    }

    // 서보를 좌우로 왕복시키며 테스트
    while (1) {
        // 0&amp;deg; &amp;rarr; 180&amp;deg;
        for (int ang = 0; ang &amp;lt;= 180; ang += 5) {
            int duty = angleToDuty(ang);
            softPwmWrite(SERVO_PIN, duty);
            delay(20);  // 펄스 간격 유지 (20 ms 주기)
        }
        // 180&amp;deg; &amp;rarr; 0&amp;deg;
        for (int ang = 180; ang &amp;gt;= 0; ang -= 5) {
            int duty = angleToDuty(ang);
            softPwmWrite(SERVO_PIN, duty);
            delay(20);
        }
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/511</guid>
      <comments>https://hotari.tistory.com/511#entry511comment</comments>
      <pubDate>Tue, 27 May 2025 16:56:07 +0900</pubDate>
    </item>
    <item>
      <title>7일차</title>
      <link>https://hotari.tistory.com/510</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.26&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상환경 (Gstreamer 사용 불가)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/05FRt/btsObsVu2N7/nmFox2RAk6eoeDO1aWNBeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/05FRt/btsObsVu2N7/nmFox2RAk6eoeDO1aWNBeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/05FRt/btsObsVu2N7/nmFox2RAk6eoeDO1aWNBeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F05FRt%2FbtsObsVu2N7%2FnmFox2RAk6eoeDO1aWNBeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;776&quot; height=&quot;539&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baufZt/btsOaPKuKrK/55s58Ex23cNtu5kfE0rXZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baufZt/btsOaPKuKrK/55s58Ex23cNtu5kfE0rXZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baufZt/btsOaPKuKrK/55s58Ex23cNtu5kfE0rXZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaufZt%2FbtsOaPKuKrK%2F55s58Ex23cNtu5kfE0rXZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;711&quot; height=&quot;781&quot; data-origin-width=&quot;711&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본환경(Gstreamer 사용 가능)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/curwcF/btsOb74rxAD/hvRKz0ghmKo4uDvK71iJCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/curwcF/btsOb74rxAD/hvRKz0ghmKo4uDvK71iJCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/curwcF/btsOb74rxAD/hvRKz0ghmKo4uDvK71iJCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcurwcF%2FbtsOb74rxAD%2FhvRKz0ghmKo4uDvK71iJCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;386&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LY4DQ/btsObsBcKYE/XfdbLNJcCewI0wWLCRVNZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LY4DQ/btsObsBcKYE/XfdbLNJcCewI0wWLCRVNZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LY4DQ/btsObsBcKYE/XfdbLNJcCewI0wWLCRVNZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLY4DQ%2FbtsObsBcKYE%2FXfdbLNJcCewI0wWLCRVNZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;386&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 실행 시 Gstreamer 사용 가능한 기본환경으로 실행되도록 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;514&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTpv63/btsOaQo6Khc/23fQYs1zoKKn35KXzmgjs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTpv63/btsOaQo6Khc/23fQYs1zoKKn35KXzmgjs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTpv63/btsOaQo6Khc/23fQYs1zoKKn35KXzmgjs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTpv63%2FbtsOaQo6Khc%2F23fQYs1zoKKn35KXzmgjs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;514&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;514&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1748226881469&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import cv2

gst = (
    &quot;v4l2src device=/dev/video0 ! &quot;
    &quot;video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! &quot;
    &quot;videoconvert ! &quot;
    &quot;video/x-raw,format=BGR ! &quot;
    &quot;appsink drop=true max-buffers=1&quot;
)
cap = cv2.VideoCapture(gst, cv2.CAP_GSTREAMER)

if not cap.isOpened():
    print(&quot;Failed to open pipeline&quot;)
    exit()

print(&quot;Pipeline opened, starting frame display&quot;)
while True:
    ret, frame = cap.read()
    if not ret:
        print(&quot;Failed to receive frame&quot;)
        break

    cv2.imshow(&quot;Live Camera&quot;, frame)
    if cv2.waitKey(1) &amp;amp; 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748305654148&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt install cmake build-essential pkg-config git

sudo apt install libjpeg-dev libtiff-dev libjasper-dev libpng-dev libwebp-dev libopenexr-dev&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-dabba9e0-1435-4132-bb76-aa1d497a14e9&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;방법 1: libjasper-dev 생략하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-4bf0adbd-e7ee-43dc-94b9-2a290e94c342&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OpenCV 대부분의 기능은 libjasper-dev 없이도 잘 동작&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1748305678604&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt install libavcodec-dev libavformat-dev libswscale-dev \
libv4l-dev libxvidcore-dev libx264-dev libdc1394-22-dev \
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;SE-bff870c2-6752-49ca-832a-304152d8d3ea&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-703e8848-294f-4209-a1c3-7b46a3fd8691&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;각 패키지 간단 설명:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-da4a8aac-33b1-470d-83da-495923049eb4&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;table style=&quot;text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;패키지&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;libavcodec-dev, libavformat-dev, libswscale-dev&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;FFmpeg 관련, 영상 코덱 인코딩/디코딩&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;libv4l-dev&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;Video4Linux &amp;ndash; 웹캠 등 비디오 입력 장치 지원&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;libxvidcore-dev, libx264-dev&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;Xvid, H.264 인코딩 라이브러리&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;libdc1394-22-dev&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;FireWire(IEEE 1394) 카메라 지원&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;libgstreamer1.0-dev, libgstreamer-plugins-base1.0-dev&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;GStreamer &amp;ndash; 멀티미디어 처리 파이프라인&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;span&gt;&lt;b&gt;[출처]&lt;/b&gt; &lt;a style=&quot;color: #000000;&quot; href=&quot;https://blog.naver.com/jjwkth2/223867559459&quot;&gt;[Rasberrypi]Open CV&lt;/a&gt;&lt;span&gt;|&lt;/span&gt;&lt;b&gt;작성자&lt;/b&gt; &lt;a style=&quot;color: #000000;&quot; href=&quot;https://blog.naver.com/jjwkth2&quot;&gt;jjwkth2&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-db0bef29-c41d-42bf-882e-684ca581e3e9&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-a240962c-f1ca-4809-aa3c-e43913df143f&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;2. 직접 빌드해서 설치 (고급, 성능 최적화 가능)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-39a0c967-cd2d-4159-aa5f-72d553e770be&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OpenCV를 직접 빌드하면, &lt;/span&gt;&lt;span&gt;&lt;b&gt;하드웨어 최적화&lt;/b&gt;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&lt;b&gt;모듈 선택&lt;/b&gt;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&lt;b&gt;CUDA 지원&lt;/b&gt;&lt;/span&gt;&lt;span&gt; 등을 세밀하게 설정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-5b8141be-cc14-44ff-bd84-2cc35738e254&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;  사전 패키지 설치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-7a3aef4f-2520-4d80-8add-2e885dc897b4&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #fdfdfd;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1748305710830&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update
sudo apt install -y build-essential cmake git pkg-config
sudo apt install -y libjpeg-dev libtiff-dev libpng-dev
sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev
sudo apt install -y libv4l-dev v4l-utils
sudo apt install -y libxvidcore-dev libx264-dev
sudo apt install -y libgtk-3-dev
sudo apt install -y libatlas-base-dev gfortran
sudo apt install -y python3-dev python3-numpy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenCV 소스 다운로드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748305727685&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ~
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
cd opencv
git checkout 4.x   # 최신 4버전 사용
cd ../opencv_contrib
git checkout 4.x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;SE-88975ec4-2459-48b8-a7d5-1010a54c0ac0&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-5ad433e1-c9be-4312-a81a-401debdd18bb&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;CMake로 빌드 설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748305746170&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D OPENCV_EXTRA_MODULES_PATH=~/Work/opencv_contrib/modules \
      -D BUILD_EXAMPLES=ON \
      -D WITH_OPENCL=ON \
      -D WITH_TBB=ON \
      -D WITH_OPENGL=ON \
      -D WITH_V4L=ON \
      -D WITH_QT=OFF \
      -D WITH_GTK=ON \
      -D WITH_FFMPEG=ON \
      -D BUILD_OPENCV_PYTHON3=ON \
      -D OPENCV_GENERATE_PKGCONFIG=ON \
      ..&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드 및 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748305763232&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;make -j$(nproc)   # 코어 수만큼 병렬 빌드
sudo make install
sudo ldconfig&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brEacr/btsOeF0lHET/Mu6On72tLbtP9OIIFmtrw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brEacr/btsOeF0lHET/Mu6On72tLbtP9OIIFmtrw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brEacr/btsOeF0lHET/Mu6On72tLbtP9OIIFmtrw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrEacr%2FbtsOeF0lHET%2FMu6On72tLbtP9OIIFmtrw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;426&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKVgUp/btsOd7Rb9CD/aMrrhYUZRjK5XqcwGZgAk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKVgUp/btsOd7Rb9CD/aMrrhYUZRjK5XqcwGZgAk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKVgUp/btsOd7Rb9CD/aMrrhYUZRjK5XqcwGZgAk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKVgUp%2FbtsOd7Rb9CD%2FaMrrhYUZRjK5XqcwGZgAk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;129&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/510</guid>
      <comments>https://hotari.tistory.com/510#entry510comment</comments>
      <pubDate>Tue, 27 May 2025 09:29:42 +0900</pubDate>
    </item>
    <item>
      <title>6일차</title>
      <link>https://hotari.tistory.com/508</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.23&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dafnpL/btsN9ebfF2t/fsebuOIo2fdkcQEfs2HicK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dafnpL/btsN9ebfF2t/fsebuOIo2fdkcQEfs2HicK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dafnpL/btsN9ebfF2t/fsebuOIo2fdkcQEfs2HicK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdafnpL%2FbtsN9ebfF2t%2FfsebuOIo2fdkcQEfs2HicK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;426&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,width=640,height=480,framerate=30/1 ! videoconvert ! jpegenc ! rtpjpegpay ! udpsink host=127.0.0.1 port=5000&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4Ky6l/btsN8ViXldC/82YZTzsd6YA5mVMI7CcYOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4Ky6l/btsN8ViXldC/82YZTzsd6YA5mVMI7CcYOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4Ky6l/btsN8ViXldC/82YZTzsd6YA5mVMI7CcYOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4Ky6l%2FbtsN8ViXldC%2F82YZTzsd6YA5mVMI7CcYOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;897&quot; height=&quot;651&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://get.videolan.org/vlc/3.0.21/win32/vlc-3.0.21-win32.exe&quot;&gt;Downloads - VideoLAN&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qv7AV/btsOaePjHTH/j79K8B5J64MVoI1ttIkiH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qv7AV/btsOaePjHTH/j79K8B5J64MVoI1ttIkiH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qv7AV/btsOaePjHTH/j79K8B5J64MVoI1ttIkiH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQv7AV%2FbtsOaePjHTH%2Fj79K8B5J64MVoI1ttIkiH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;423&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfOqrK/btsN9E8CxnP/KQYkYmGEbqqmnCsa4U0N50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfOqrK/btsN9E8CxnP/KQYkYmGEbqqmnCsa4U0N50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfOqrK/btsN9E8CxnP/KQYkYmGEbqqmnCsa4U0N50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfOqrK%2FbtsN9E8CxnP%2FKQYkYmGEbqqmnCsa4U0N50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1187&quot; height=&quot;456&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;568&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca8vM7/btsN9fBg0d5/iwjw2B9mk37iBFeEZAlNb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca8vM7/btsN9fBg0d5/iwjw2B9mk37iBFeEZAlNb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca8vM7/btsN9fBg0d5/iwjw2B9mk37iBFeEZAlNb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca8vM7%2FbtsN9fBg0d5%2Fiwjw2B9mk37iBFeEZAlNb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;568&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;568&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  목표&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Raspberry Pi에 연결된 &lt;b&gt;USB 웹캠 영상&lt;/b&gt;을 &amp;rarr; GStreamer로 캡처하여 &amp;rarr; RTSP 서버로 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rArr; 다른 장치에서 실시간 스트리밍 가능 (VLC, OpenCV 등으로 수신)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  시스템 구성&lt;/h2&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;[ Raspberry Pi ]
 └── USB Webcam
     └── GStreamer Pipeline
         └── RTSP 서버 (ex: gst-rtsp-server)
             └── RTSP 클라이언트(다른 PC, VLC 등)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 방법 1: GStreamer + gst-rtsp-server 사용 (Python X)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  사전 설치&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;sudo apt update
sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good    gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  UDP 서버 실행 (예: 640x480 MJPEG)&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;gst-launch-1.0 v4l2src device=/dev/video0 ! \\
video/x-raw,width=640,height=480,framerate=30/1 ! \\
videoconvert ! \\
x264enc tune=zerolatency ! rtph264pay config-interval=1 pt=96 ! \\ 
udpsink host=127.0.0.1 port=5000
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 기본 UDP 전송 예제이며, RTSP 서버 구성이 필요할 경우 gst-rtsp-server를 Python 또는 C로 직접 작성해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;v=0
c=IN IP4 &amp;lt;127.0.0.1&amp;gt;
m=video 5000 RTP/AVP 96
a=rtpmap:96 H264/90000
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 방법 2: Python + GStreamer + RTSP Server 연동&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  GStreamer 기반 Python RTSP 스트림 생성 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 코드로 스트리밍 파이프라인 구성:&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;pip install opencv-python
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import cv2
import subprocess

cap = cv2.VideoCapture(0)  # /dev/video0

gst_cmd = (
    &quot;gst-launch-1.0 -v fdsrc ! videoparse width=640 height=480 format=rgb &quot;
    &quot;! videoconvert ! x264enc tune=zerolatency bitrate=512 speed-preset=superfast &quot;
    &quot;! rtph264pay config-interval=1 pt=96 ! udpsink host=127.0.0.1 port=5000&quot;
)

process = subprocess.Popen(gst_cmd, shell=True, stdin=subprocess.PIPE)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    process.stdin.write(frame.tobytes())
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 방법 3: gst-rtsp-server (C or Python) 사용&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GStreamer 공식 RTSP 서버 라이브러리:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소스: &lt;a href=&quot;https://github.com/GStreamer/gst-rtsp-server&quot;&gt;https://github.com/GStreamer/gst-rtsp-server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Raspberry Pi에 빌드하거나 Python 바인딩(py-gst) 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 코드 참고:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-launch.c&quot;&gt;https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-launch.c&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ RTSP 클라이언트에서 수신 (VLC, OpenCV 등)&lt;/h2&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;vlc rtsp://&amp;lt;raspberrypi-ip&amp;gt;:8554/test
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 OpenCV에서:&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;cap = cv2.VideoCapture(&quot;rtsp://192.168.0.10:8554/test&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  테스트 팁&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Raspberry Pi에서 v4l2-ctl --list-formats-ext -d /dev/video0 명령어로 해상도/포맷 확인&lt;/li&gt;
&lt;li&gt;초기에 MJPEG 포맷이 안정적이며 H264로 전환 시 GPU 부하 주의&lt;/li&gt;
&lt;li&gt;RTSP 포트(8554) 방화벽 열려 있어야 외부 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GStreamer 개요 및 기본 구조 이해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  목표: GStreamer의 기본 철학, 구조, 구성 요소(Element, Pad, Pipeline 등)를 이해하고 CLI 도구를 활용한 구조 확인을 시도한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  꼭 설명할 개념 + 상세 설명&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;GStreamer란 무엇인가?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GStreamer는 영상, 오디오, 네트워크 스트리밍 등 모든 멀티미디어 흐름을 처리할 수 있는 오픈소스 프레임워크입니다.&lt;/li&gt;
&lt;li&gt;플러그인 기반 구조로 매우 유연하고 확장성이 높습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pipeline(파이프라인) 구조 이해&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이프라인은 여러 요소(Element)를 ! 기호로 연결한 데이터 흐름 구조입니다.&lt;/li&gt;
&lt;li&gt;데이터를 처음부터 끝까지 순차적으로 처리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Element란 무엇인가?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GStreamer의 구성 단위로, 각 Element는 특정 기능을 수행합니다. 예: videotestsrc(소스), autovideosink(출력)&lt;/li&gt;
&lt;li&gt;Source, Filter, Sink 타입으로 구분됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pad란 무엇인가?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pad는 Element의 입출력 인터페이스입니다.&lt;/li&gt;
&lt;li&gt;src pad는 데이터를 내보내고, sink pad는 데이터를 받습니다.&lt;/li&gt;
&lt;li&gt;Element 간 연결은 pad를 통해 이루어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Capabilities (Caps)의 개념&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 포맷/속성(해상도, 프레임률, 색상 포맷 등)을 명시하는 구조입니다.&lt;/li&gt;
&lt;li&gt;서로 다른 Element 간 데이터 연결 가능 여부를 결정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Push vs Pull 모드&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Push 모드: Source가 데이터를 밀어넣음 (실시간 스트림)&lt;/li&gt;
&lt;li&gt;Pull 모드: Sink가 데이터를 끌어옴 (파일 읽기 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;플러그인 기반 아키텍처&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GStreamer는 수백 개의 플러그인으로 기능이 확장됩니다.&lt;/li&gt;
&lt;li&gt;필요 시 사용자 정의 플러그인도 제작 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;gst-launch-1.0 도구 소개&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이프라인을 CLI로 실행할 수 있는 명령어입니다.&lt;/li&gt;
&lt;li&gt;GStreamer 실습의 핵심 도구로, 빠른 테스트에 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;gst-inspect-1.0 도구 사용법&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 Element의 상세한 정보(설정값, 가능한 caps, pad 연결 정보 등)를 보여줍니다.&lt;/li&gt;
&lt;li&gt;예: gst-inspect-1.0 videoconvert&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;설치 및 버전 확인 방법&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설치: sudo apt install gstreamer1.0-tools&lt;/li&gt;
&lt;li&gt;버전 확인: gst-launch-1.0 --version&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ 시범 시연&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;bash
복사편집
gst-launch-1.0 videotestsrc ! autovideosink

&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 패턴 영상 출력 확인&lt;/li&gt;
&lt;li&gt;Ctrl+C로 중지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  실습 과제&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;videotestsrc, audiotestsrc, audioconvert, autoaudiosink 등을 조합한 파이프라인 구성 실습&lt;/li&gt;
&lt;li&gt;gst-inspect-1.0 명령어를 사용해 3개의 Element 정보를 조사하고 발표하기&lt;/li&gt;
&lt;li&gt;CLI 기반으로 caps 정보 검색 및 출력 포맷 비교 실습&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;과제 1:&lt;/b&gt; videotestsrc, audiotestsrc 조합 파이프라인 구성&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;bash
복사편집
gst-launch-1.0 videotestsrc ! autovideosink
gst-launch-1.0 audiotestsrc ! autoaudiosink

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;과제 2:&lt;/b&gt; gst-inspect-1.0 videotestsrc 결과 분석 예시&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# 출력 중 주요 부분:
Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw
          format: (string)I420
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  수업 목표&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GStreamer의 파이프라인 구성을 심화하여 다양한 필터와 옵션을 적용하는 법을 익힌다.&lt;/li&gt;
&lt;li&gt;capsfilter, videoconvert, filesink 등을 활용한 &lt;b&gt;실제 응용 파이프라인 작성&lt;/b&gt;을 실습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  핵심 개념 + 상세 설명&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Element 간 연결 (!)의 의미&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;! 기호는 Element를 연결하며, 내부적으로는 pad를 연결함.&lt;/li&gt;
&lt;li&gt;파이프라인 데이터 흐름은 왼쪽 &amp;rarr; 오른쪽으로 진행됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;capsfilter의 개념과 사용 목적&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;capsfilter는 특정 포맷, 해상도, 프레임레이트 등으로 &lt;b&gt;데이터 포맷을 고정&lt;/b&gt;하는 역할.&lt;/li&gt;
&lt;li&gt;파이프라인 내 Element 간 caps negotiation을 명시적으로 조절함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;caps 표현 형식&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: video/x-raw, width=640, height=480, framerate=30/1&lt;/li&gt;
&lt;li&gt;쉼표로 구분된 속성들은 AND 조건, 여러 옵션은 OR 형태로 caps 표현 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;videotestsrc의 다양한 pattern 사용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본값: smpte, 기타 예: ball, snow, zone-plate&lt;/li&gt;
&lt;li&gt;패턴을 바꾸면 영상 시각적 특성이 달라짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;videoconvert의 중요성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서로 다른 색상 포맷 간 자동 변환을 지원함.&lt;/li&gt;
&lt;li&gt;영상 출력 전 videoconvert가 없으면 sink와 연결 실패 가능성 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;autovideosink의 동작 방식&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템에 설치된 sink를 자동 선택함 (Xv, OpenGL, Wayland 등)&lt;/li&gt;
&lt;li&gt;교차 호환성을 위해 권장되는 Sink&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;gst-inspect를 활용한 caps 확인&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출력 가능한 형식 및 지원 범위를 직접 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;gst-inspect-1.0 videotestsrc | grep Caps&lt;/li&gt;
&lt;li&gt;&lt;b&gt;filesink Element를 통한 출력 저장&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;filesink location=output.raw 과 같이 사용&lt;/li&gt;
&lt;li&gt;인코딩하지 않은 raw 영상 저장 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파이프라인 오류 발생 예시와 분석&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;caps 불일치, 누락된 필터, 싱크 미설치 시 negotiation failure 발생&lt;/li&gt;
&lt;li&gt;예외 메시지 해석 연습&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프레임레이트 설정 방식&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;framerate=15/1, framerate=30/1 등으로 설정&lt;/li&gt;
&lt;li&gt;일부 Element는 정확한 fps 지정 없이는 작동 안 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dot 파일로 파이프라인 구조 시각화&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;환경 변수로 .dot 파일 생성 &amp;rarr; Graphviz로 시각화 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;GST_DEBUG_DUMP_DOT_DIR=/tmp gst-launch-1.0 ...
dot -Tpng /tmp/pipeline.dot -o output.png
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  실습 과제&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;과제 1: 해상도 지정 파이프라인 구성&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;gst-launch-1.0 videotestsrc ! video/x-raw,width=320,height=240 ! autovideosink
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  결과: 320x240 해상도로 출력되는 테스트 영상&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;과제 2: fps 조절 + pattern 변경 조합 실습&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;gst-launch-1.0 videotestsrc pattern=ball ! video/x-raw,framerate=10/1 ! videoconvert ! autovideosink
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  결과: 낮은 fps로 천천히 움직이는 볼 패턴 영상 출력&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;과제 3: 파일로 영상 저장&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;gst-launch-1.0 videotestsrc num-buffers=100 ! video/x-raw,format=I420 ! filesink location=test.raw
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  결과: 100프레임 분량의 raw 영상이 test.raw 파일로 저장됨&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  예제 코드 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num-buffers: 생성할 프레임 수 제한&lt;/li&gt;
&lt;li&gt;video/x-raw, format=I420: 기본 색상 포맷 지정&lt;/li&gt;
&lt;li&gt;videoconvert 생략 시 오류 발생 가능 (sink의 요구 형식과 불일치할 경우)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 결과 검증 방법&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저장된 파일 확인:&lt;/li&gt;
&lt;li&gt;ls -lh test.raw&lt;/li&gt;
&lt;li&gt;caps 설정 변경에 따른 출력 영상 변화를 직접 시각적으로 비교&lt;/li&gt;
&lt;li&gt;잘못된 파이프라인 실행 시 ERROR: from element 로그 해석 훈련&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이에서 웹캠 이미지 실시간 송출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 웹캠 이미지 실시간 수신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이 터미널 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gst-launch-1.0&amp;nbsp;v4l2src&amp;nbsp;device=/dev/video0&amp;nbsp;!&amp;nbsp;video/x-raw,&amp;nbsp;width=640,&amp;nbsp;height=480,&amp;nbsp;framerate=30/1&amp;nbsp;!&amp;nbsp;videoconvert&amp;nbsp;!&amp;nbsp;x264enc&amp;nbsp;tune=zerolatency&amp;nbsp;bitrate=800&amp;nbsp;speed-preset=superfast&amp;nbsp;!&amp;nbsp;rtph264pay&amp;nbsp;config-interval=1&amp;nbsp;pt=96&amp;nbsp;!&amp;nbsp;udpsink&amp;nbsp;host=10.10.16.11&amp;nbsp;port=5000&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 텍스트 파일&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1576x/btsN9znveEa/TfqRKhbuadqiCvEjjHLItK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1576x/btsN9znveEa/TfqRKhbuadqiCvEjjHLItK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1576x/btsN9znveEa/TfqRKhbuadqiCvEjjHLItK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1576x%2FbtsN9znveEa%2FTfqRKhbuadqiCvEjjHLItK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;277&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3And/btsN9fa599B/DAJLpkmuSfGlrkEhMNp31k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3And/btsN9fa599B/DAJLpkmuSfGlrkEhMNp31k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3And/btsN9fa599B/DAJLpkmuSfGlrkEhMNp31k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3And%2FbtsN9fa599B%2FDAJLpkmuSfGlrkEhMNp31k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1242&quot; height=&quot;579&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sVC9a/btsN9dxE2oY/QkgkDOoXutMUTTKndKf5W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sVC9a/btsN9dxE2oY/QkgkDOoXutMUTTKndKf5W0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sVC9a/btsN9dxE2oY/QkgkDOoXutMUTTKndKf5W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsVC9a%2FbtsN9dxE2oY%2FQkgkDOoXutMUTTKndKf5W0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1070&quot; height=&quot;496&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo lsof /def/video0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo kill -9 (번호)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpZcfx/btsN9yWssz9/9j4QJDM4wKBeMnzlk8IKZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpZcfx/btsN9yWssz9/9j4QJDM4wKBeMnzlk8IKZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpZcfx/btsN9yWssz9/9j4QJDM4wKBeMnzlk8IKZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpZcfx%2FbtsN9yWssz9%2F9j4QJDM4wKBeMnzlk8IKZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;878&quot; height=&quot;80&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcbAaH/btsN9MUqKaQ/PdiUAbdGXzcwKfmDKwJ2h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcbAaH/btsN9MUqKaQ/PdiUAbdGXzcwKfmDKwJ2h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcbAaH/btsN9MUqKaQ/PdiUAbdGXzcwKfmDKwJ2h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcbAaH%2FbtsN9MUqKaQ%2FPdiUAbdGXzcwKfmDKwJ2h1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;237&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간 웹캠 영상 녹화 후 저장&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbJK5k/btsOats6GCA/STUXOJCpnUkXkmXSGT1410/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbJK5k/btsOats6GCA/STUXOJCpnUkXkmXSGT1410/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbJK5k/btsOats6GCA/STUXOJCpnUkXkmXSGT1410/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbJK5k%2FbtsOats6GCA%2FSTUXOJCpnUkXkmXSGT1410%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1301&quot; height=&quot;417&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8096-9991-ee3d8e12f8c4&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;h3 contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot; data-ke-size=&quot;size23&quot;&gt;카메라 입력 처리 (v4l2src)&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80d4-8339-c3185b58c0e2&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWhzzw/btsOa6cR5sD/ju6KWcLOtMYY1WTHzfmTyk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWhzzw/btsOa6cR5sD/ju6KWcLOtMYY1WTHzfmTyk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWhzzw/btsOa6cR5sD/ju6KWcLOtMYY1WTHzfmTyk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bWhzzw/btsOa6cR5sD/ju6KWcLOtMYY1WTHzfmTyk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1&quot; height=&quot;1&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
목표: Raspberry Pi 또는 일반 Linux 환경에서 USB 웹캠을 GStreamer에 연결하고, 실제 영상을 캡처하여 파이프라인으로 처리할 수 있도록 한다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8007-802f-c5dc7fd10b01&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8061-96ee-e24588292bac&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NDkYK/btsOahNjc5I/9WH3TkPzzroemOA2XFXAL1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NDkYK/btsOahNjc5I/9WH3TkPzzroemOA2XFXAL1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NDkYK/btsOahNjc5I/9WH3TkPzzroemOA2XFXAL1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/NDkYK/btsOahNjc5I/9WH3TkPzzroemOA2XFXAL1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1&quot; height=&quot;1&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h4 contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot; data-ke-size=&quot;size20&quot;&gt;꼭 설명할 개념 + 상세 설명&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8085-9ef9-c284631b910c&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;/dev/video0&lt;/span&gt;&lt;span data-token-index=&quot;1&quot;&gt;의 의미와 다중 장치 식별&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80a3-9466-c79892e6a1f1&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;Linux 시스템에서 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;/dev/video0&lt;/span&gt;, &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;3&quot;&gt;/dev/video1&lt;/span&gt;은 각각의 비디오 입력 장치를 나타냅니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80a7-bfda-cbf2827ca173&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;웹캠이 하나만 연결되어 있다면 보통 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;/dev/video0&lt;/span&gt;에 해당합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80e1-acae-ce08a0cf75af&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;ls /dev/video*&lt;/span&gt;로 연결 상태를 확인하고, &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;2&quot;&gt;v4l2-ctl --list-devices&lt;/span&gt;로 장치 목록 조회 가능.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8067-b8d3-e17c88cd6769&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;v4l2src Element의 역할&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80d5-904a-cb711882e63a&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;v4l2src&lt;/span&gt;는 Video4Linux2 장치 인터페이스를 통해 웹캠에서 실시간으로 영상을 받아오는 GStreamer Source Element입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8048-9dc5-fd3d83f9d48d&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;Raspberry Pi나 USB 기반 웹캠에서 모두 사용할 수 있음.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-805f-ac27-cc43c086a96a&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;웹캠 장치 지원 포맷 확인&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-803b-908c-d3b4fa1098d2&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 v4l2-ctl --list-formats-ext &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80b8-be72-dbe17867fbd9&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;출력되는 포맷(MJPEG, YUYV 등)과 해상도/프레임레이트 목록을 바탕으로 GStreamer 파이프라인 구성 필요.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8045-b199-d658dd764993&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;지원 포맷에 맞는 caps 명시&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-806f-9a1a-fed9e59a8d50&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;v4l2src&lt;/span&gt;는 장치에서 지원하는 포맷과 해상도로만 데이터를 출력 가능함.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80c8-9ca1-f4632870c684&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;예시:&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8025-a751-d8d7fe70576b&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 gst-launch-1.0 v4l2src &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; video/x-raw, &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;640&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;480&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; autovideosink &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80ff-a237-f3d20674ca09&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;MJPEG과 YUY2(YUYV)의 차이&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-802a-bcf6-d264e7edca0a&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;MJPEG: 이미 압축된 JPEG 프레임을 순차적으로 전송 &amp;rarr; CPU 부하 적음&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80d4-8879-c340a3739b5e&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;YUY2: 압축되지 않은 RAW 포맷 &amp;rarr; 후속 변환 필수&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8007-9df3-e55a2e56bbc8&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;videoconvert 필수성&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-809c-81d2-c289c897df6b&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;v4l2src&lt;/span&gt;에서 출력된 포맷이 Sink와 맞지 않으면 중간에 변환 Element 필요&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8007-bcb4-dd8751b69b8f&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;예: MJPEG &amp;rarr; RGB &amp;rarr; autovideosink 출력 위해 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;jpegdec&lt;/span&gt; + &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;3&quot;&gt;videoconvert&lt;/span&gt; 필요&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80c3-aba2-f8748aaadda1&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;sync=false 설정 이해&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8078-a477-c63d0540c983&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;실시간 성능 향상을 위해 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;autovideosink sync=false&lt;/span&gt; 옵션을 사용하면 버퍼 지연 없이 출력 가능&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-805f-9bfc-db41f278460d&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;지연 시간이 문제될 경우 유용함&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8047-9cc4-d498b65f6cde&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;fps 조절 (프레임레이트 설정)&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8006-ab44-e197e763ccbe&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 video/x-raw, &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;framerate&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;30&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;/1 &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-808f-841b-dbf359ffd473&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;웹캠이 지원하는 최대 프레임레이트 확인 후 설정해야 함&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-8045-8269-d463c1395e33&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;잘못 설정 시 pipeline negotiation 실패 발생&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-808b-b9ea-e55edc818b6e&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;latency 및 출력 지연 분석&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-80ec-9e07-caa60c6f7921&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;MJPEG과 YUYV 포맷 비교 시 latency 차이 체험&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-block-id=&quot;1fb8b5a1-e8a9-808a-9d26-dbe48c2c706b&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;실시간 영상 처리에 있어 필터 수, 포맷 복잡도 등이 지연에 영향을 줌&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8072-ab00-ee12ce14543f&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;다양한 Sink 조합&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8043-8b41-c1c0b433c414&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;autovideosink&lt;/span&gt;, &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;2&quot;&gt;glimagesink&lt;/span&gt;, &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;4&quot;&gt;fakesink&lt;/span&gt; 등 다양한 출력 장치 실험&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8032-b5dd-f94a387acef6&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;Raspberry Pi에서는 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;glimagesink&lt;/span&gt;가 GPU 가속 지원&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8017-b6e9-c85c6e2d40ae&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80cc-b87c-f2960b873000&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVPAEk/btsObxufzbC/wg54xELVlfI7Wxdf3f1gpK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVPAEk/btsObxufzbC/wg54xELVlfI7Wxdf3f1gpK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVPAEk/btsObxufzbC/wg54xELVlfI7Wxdf3f1gpK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bVPAEk/btsObxufzbC/wg54xELVlfI7Wxdf3f1gpK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1&quot; height=&quot;1&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h4 contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot; data-ke-size=&quot;size20&quot;&gt;시범 시연&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8021-b783-c5e436131267&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 &lt;/span&gt;&lt;span style=&quot;color: #708090;&quot; data-token-index=&quot;0&quot;&gt;# 기본 실시간 영상 출력&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; gst-launch-1.0 v4l2src &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;device&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;/dev/video0 &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; videoconvert &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; autovideosink &lt;/span&gt;&lt;span style=&quot;color: #708090;&quot; data-token-index=&quot;0&quot;&gt;# MJPEG 포맷을 명시&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; gst-launch-1.0 v4l2src &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;device&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;/dev/video0 &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; image/jpeg, &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;1280&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;720&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; jpegdec &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; videoconvert &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; autovideosink &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8056-9979-f69edbeed201&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80e2-86c6-d8370bfbfa9a&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hqeyr/btsOaYsDfXf/9gYbOOkLaU5p3ayaCVHn5K/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hqeyr/btsOaYsDfXf/9gYbOOkLaU5p3ayaCVHn5K/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hqeyr/btsOaYsDfXf/9gYbOOkLaU5p3ayaCVHn5K/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/Hqeyr/btsOaYsDfXf/9gYbOOkLaU5p3ayaCVHn5K/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1&quot; height=&quot;1&quot; data-origin-width=&quot;1&quot; data-origin-height=&quot;1&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h4 contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot; data-ke-size=&quot;size20&quot;&gt;실습 과제&lt;/h4&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80fc-b5bf-df42833032db&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;v4l2-ctl&lt;/span&gt;을 사용해 사용 가능한 해상도와 포맷을 조사하고 노트에 정리&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-806c-ac73-c1408148557c&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;MJPEG / YUYV 포맷 각각을 이용해 영상 출력 파이프라인 구성&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80b1-b370-d9408bd126bb&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;sync=false&lt;/span&gt; vs 기본 모드의 출력 지연 차이 비교&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8036-a2bf-cfd0306e442d&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;해상도별 처리 속도 차이 비교 (640x480 / 1280x720 / 1920x1080)&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8080-838c-eee2862cb8b7&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div contenteditable=&quot;false&quot; data-text-edit-side=&quot;start&quot; data-content-editable-void=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: start;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;파이프라인 중 &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;videoconvert&lt;/span&gt; 제거 후 오류 발생 여부 확인&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80a0-a1cf-f57cb8853730&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;과제 1:&lt;/span&gt; 포맷 확인&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-800d-a60d-ecfa635f1d82&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 v4l2-ctl --list-formats-ext &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80bd-93a0-e9f26cd60ede&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;과제 2:&lt;/span&gt; MJPEG 기반 웹캠 출력&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-80f7-9033-ce4a29409456&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 gst-launch-1.0 v4l2src &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; image/jpeg,width&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;1280&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;,height&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #990055;&quot; data-token-index=&quot;0&quot;&gt;720&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; jpegdec &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; autovideosink &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
​&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-8037-af28-fd3a7ae43400&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;과제 3:&lt;/span&gt; &lt;span style=&quot;background-color: #000000; color: #eb5757;&quot; data-token-index=&quot;2&quot;&gt;sync=false&lt;/span&gt; 실험&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #32302c; text-align: start;&quot; data-block-id=&quot;1fb8b5a1-e8a9-802d-b6d6-fad47b5a6f04&quot;&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f7f6f3; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-void=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div data-popup-origin=&quot;true&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;Shell&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;color: #73726e;&quot;&gt;
&lt;div style=&quot;background-color: #eae9e5; color: #32302c;&quot;&gt;복사&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #32302c; text-align: left;&quot; contenteditable=&quot;false&quot; data-content-editable-leaf=&quot;true&quot;&gt;&lt;span style=&quot;color: #dd4a68;&quot; data-token-index=&quot;0&quot;&gt;bash&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; 복사편집 gst-launch-1.0 v4l2src &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; videoconvert &lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;!&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt; autovideosink &lt;/span&gt;&lt;span style=&quot;color: #ee9900;&quot; data-token-index=&quot;0&quot;&gt;sync&lt;/span&gt;&lt;span style=&quot;background-color: #000000; color: #9a6e3a;&quot; data-token-index=&quot;0&quot;&gt;=&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;false&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/508</guid>
      <comments>https://hotari.tistory.com/508#entry508comment</comments>
      <pubDate>Fri, 23 May 2025 16:51:05 +0900</pubDate>
    </item>
    <item>
      <title>IM 시리즈</title>
      <link>https://hotari.tistory.com/507</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;대답의 처음 5초는 스크립트 냄새가 난다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문에 어떻게 대답을 시작할 지 미리 연습하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작하는 방법이 매번 다를 수 있을 정도로 다양해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 그 자리에서 바로 생각하는 것처럼 들리는 것이 중요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) Well... / You know... / Let me see... / Oh, you wanna know about... / etc&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 중요한 영어 공부법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 컨트롤 전략 &amp;rarr; MP &amp;rarr; 나머지 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. MP &amp;rarr; 컨트롤 전략 &amp;rarr; 나머지 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MP 마스터하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대답은 2분 내로 짧고 깔끔하게 하는 것이 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MP를 통해 요점을 깔끔하게 말할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일부러 길게 말할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 연습할 때는 엄청 간단히 짧게 한 문장으로 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;질문 컨트롤하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 포괄적으로 질문 &amp;rarr; 하나로 답하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- general &amp;rarr; singular control 전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대화하는 느낌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;질문 들을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 처음 들을 때 Topic과 카테고리가 무엇인지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 두 번째 들을 때 카테고리에 따른 전략 생각하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 카테고리 모르겠거나 무슨 질문인지 이해안가면 과갑하게 스킵&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;7규칙&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 질문할 때는 대답이 필요없는 질문으로 하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 불편하고 어려운 단어 사용하지 않기 (사용하기 편하고 자신 있는 간단한 단어 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 한 문장에서 같은 단어 반복 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 무언가를 묘사하거나 감정단어 2개를 말할 때 'and' 사용하지 말고 단어 2개를 두 문장으로 나누기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 한 가지에 대해서만 말하기, 질문이 여러 개이면 하나를 선택해서 집중적으로 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 긴장이 되고 할 일이 없을 땐 바로 결론으로 가기 (너무 짧아도 그냥 끝내기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. '솔직한 변명'은 나중에 하기, 처음 부분에서 하지 않기, 두괄식으로 말하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Combo Set&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. description + past experience&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. habit + past experience&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. comparison + past experience&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 의사소통 기술 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문법을 잘 하는 것처럼 보이게 하기 위해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4 카테고리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Description 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Habit 습관&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Past Experience 과거 경험 (제일 중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Comparison 비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 문법보다 과거 문법이 제일 중요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 질문을 연습하더라도 과거형으로 대답하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대답을 깔끔하게 하는법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 4가지 카테고리에 따라 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 설명과 습관에 대한 대답은 짧다고 느껴지는 정도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- quick comparison 전략 &amp;rarr; 과거에 대해 살짝 이야기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Description 전략 (설명 / 묘사)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 짧게 이야기하고 넘어가도 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 15번 문제에 나오면 빠른 비교로 보충 설명하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MP 2문장으로 설명 : 좋은지 싫은지, 그 이유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- people (MP) &amp;rarr; me (나의 생각) &amp;rarr; 감정 넣어서 설명 &amp;rarr; 돌아가서 다시 MP 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 말하고 싶은 것 말하기 (MP)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 어떻게 느끼는지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 왜 그렇게 느끼는지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) My favorite ~ 대신 사용하기 좋은 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I like / I really like / I love / I really love / etc&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- What I reaaly love/like/hate about ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Habit 전략 (습관)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적인 MP 설명 : 감정 설명 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 항상 현재나 미래로 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 반드시 '한가지'에 대해서 말할 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 설명보다는 행동 묘사하는 질문일 경우에 해당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;usually do&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;first thing that you do&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스크립트 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 표현만 익히고 샘플 외우지 말고 프리토킹&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 살짝 변형해서 본인의 것으로 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 뭐하는지 나의 습관 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 나한테는 너무 중요하다고 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3, 4. 프리토킹&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5, 6. 빠른 비교 (과거 &amp;rarr; 현재)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빠른 비교 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 빨리 과거로 갔다가 바로 원래 이야기로 돌아오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예전에는 이랬는데 요새는 이렇다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1, 2 문장 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) I never really did this before, but nowadays, I just love doing this. I just can't explain it.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Past Experience 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MP에 클라이맥스를 미리 말하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주제를 예측할 수 있도록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. MP (무엇을, 어떻게, 왜)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Direct quatation (직접화법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IM : 직접화법 = 나에 대해서 집중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IH : 직접화법 + 간접화법 = 나 + 다른 사람 (내가 이렇게~, 그/그녀가 이렇게~) (이름 직접 언급하면 더 자연스러움)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Comparison 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= description 전략 + past experience 전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비교 질문에&amp;nbsp; 대답하는데 멘붕이 될 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 스킵&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이미 대답을 시작했다면 : MP없이 바로 과거부터 설명, 과거 사실에 집중 &amp;rarr; 현재 설명 &amp;rarr; 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간 비교 전략&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. MP : Pure present&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전 현재형으로, 현재에 대해서만 집중해 간단하게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 과거에 대해서만 말하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 현재 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 비교 전략 (none-time)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. general MP (전반적인 이야기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. A 설명 &amp;rarr; B 설명 &amp;rarr; 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Habit 예시&lt;/li&gt;
&lt;li&gt;Bank 은행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) What do you usually do whenever you go to the bank?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[무조건] No matter what&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[있잖아]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Well, here's the thing&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I'll tell you what&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You know what?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[내가 ~할 때, 나는 ~ 한다]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Whenever I ~ I always make sure to ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Every time ~ I always check to see that/if I have ~ with me.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[이건 정말 중요해요. 왜냐하면 ~]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This is crucial because ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This is very important because ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I find this very important to me because ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[~할 수 밖에 없었다] I was forced ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[아무것도 할 수 없었다]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I wasn't able to do anything ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I couldn't do anything ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Transportation 교통&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;메인 포인트&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본구조, 1가지에 대해서만 말하도록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. No matter what,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;whenever I need to go somewhere.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I always take the 'subway or bus'.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. This is crucial,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It's quite rare for me to take other potions.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;부연설명, 프리스타일&amp;gt; how &amp;rarr; why 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. I love 'how' I can read something while taking the public transit.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. It's the only time I can actually (정말로, 진짜로) read.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;빠르게 과거로 갔다가 현재로 돌아오기&amp;gt; 빠른 비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. It's interesting cos I've never liked reading before.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. I still don't, but I love how it helps me to kill time especially while I'm commuting.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recycling 재활용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;메인포인트&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Every time I need to recycle, I always check to see that all the cans and plastic bottles are crushed to save space.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. This is very important.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It's really rare for me to forget to check.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;프리스타일&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. I'm quite lazy so I hate having to recycle if I don't have to.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. I take out the recycling only when my bins are full to the max.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;빠른 비교&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. It's interesting cos I had to recycle nearly every day before.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. But now, with my new method of cushing everything. I recycle every 2 weeks.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Appointments 예약&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. I'll tell you what. I always make a hair appointment pretty much every 2 weeks.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. I find this very important. It's very rare for me to skip a hair-cut.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Of course, I make other appointments as well in my life, but this one is the most important to me.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. My hair has a mind of its own, so I need it to be well maintained.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. It's interesting cos I never cared about my hair before.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. But these days, I feel my hair gives me confidence.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Filler 필러&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필러는 엑스트라 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 빨리 말해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대화가 부드럽게 만들어주는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- you know, right, um('엄...')&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) When ever I recycle right, I always make sure to you know tie my bag.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추천 표현/문장/감탄사&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Wow, It's quite a tough question.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Wow, That's tough.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Wow, Ididn't expect such a hard question.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Wow, That's not an easy question.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대답 시작 시 Umm... 길게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 같은 것을 다시 설명할 때 you know ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다른 것을 부연 설명할 때 I mean ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 나의 생각, 감정 나타내기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I love ~ / I think ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- (내가 이렇게 느꼈다) 감정표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I feel/felt like&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ~한 기분이 든다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It makes me feel ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- even : 놀라운 것에 대한 대답에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Oh : oh로 시작하여 질문 BUT 어색한 질문 금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- wanna : 발음 부드럽게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- (looks) like : similar (직유법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- home : house, apartment 대신 집 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- space : place 대신 장소 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- usually : 보통&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- just : '단지' 주어 바로 뒤에 자연스럽게 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- That's why : 그러니까, 그래서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 질문 복기, alright ~ : 짧은 문장으로 질문 복기해 생각하고 있음을 보여줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It's just right for me.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It's perfect.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- And you know what? 그리고 있잖아요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I just don't know why!&amp;nbsp; 나도 이유를 모르겠어!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I just can't explain! 설명은 못하겠어!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Whether I like it or not 좋던 싫던&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- as I already told you before 내가 전에 말했던 것처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- don't get me wrong 오해하진 마&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I love them to death 그들을 죽을만큼 사랑해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- That's all / That's it / Thank you 사용 금지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주제별 표현&lt;/li&gt;
&lt;li&gt;집&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- low rent &amp;rarr; save money&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- less cleaning &amp;rarr; save time&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- stronger wifi signal&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I'm barely/rarely home&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I'm like never home&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I only come home to sleep&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- everything what I want 대신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I can do whatever I feel like.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I really love having my own time. It's the best.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It helps me to relax&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It makes me feel so good to watch movies all day.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I can't remember very specifically, but one thing I do remember is that it was clearly a huge house.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Even though it's definitely a bigger place. I still feel like it's not that big.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- My place is big, but I still want a bigger place.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;휴가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- So, whether I like it or not.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I have to be with my parents.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I have no choice but to be with my parents.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I'm totally stuck with my parents.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I'm not an outgoing person at all.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I'm not extroverted at all.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- So, I prefer to be by myself.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- So, I prefer to spend time alone.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ~ rather than spend time with someone.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ~ rather than hang out/meet people/go out&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I really hope I can move out soon.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- I really want to get out of here soon.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- out of은 [outta]로 부드럽게 발음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방구 표현 4가지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- fart = 방구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- let it rip / let one rip&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cut cheese&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- thunder from down under&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- silent but deadly&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응가 표현 4가지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- number 1 (소변)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- number 2 (대변)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- take a dump 응가 마렵다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- deuce it 응가하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;집 설명&amp;nbsp;&amp;rarr; MP 살리기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. You know, I got to say, what I really love about my place is my storage room.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. It's just so spacious.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. You see, My home isn't all that big.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. But, you know, it's not all that small either.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. But none of that really matters I guess because I love how big my storage room is.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패션 묘사&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. What do people usually wear in your country?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. You know, I gotta say, what I really hate about fashion here in Korea is that people tend to only wear safe colors.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. I find it quite boring (find it = think, quite = little, so)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. You see, for me, I try not to follow those trends.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. I try to be as colorful as possible.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. I guess, you can say that I like to stand out.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가구 묘사&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. Tell me about the furniture in your home.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. What I really find interesting about my work dsek is that it's the only dark furniture I have at home.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. It's completely black and totally stands out in my living room.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. It's funny cos (all) my other furniture is light in color.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. black 책상 이야기&lt;/p&gt;</description>
      <category>OPIC 공부/오픽노잼</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/507</guid>
      <comments>https://hotari.tistory.com/507#entry507comment</comments>
      <pubDate>Fri, 23 May 2025 16:08:52 +0900</pubDate>
    </item>
    <item>
      <title>5일차</title>
      <link>https://hotari.tistory.com/506</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.22&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bitkkx/btsN7CcmAXT/UkrihZktZwEoRcKboYMpQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bitkkx/btsN7CcmAXT/UkrihZktZwEoRcKboYMpQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bitkkx/btsN7CcmAXT/UkrihZktZwEoRcKboYMpQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbitkkx%2FbtsN7CcmAXT%2FUkrihZktZwEoRcKboYMpQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;817&quot; height=&quot;631&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pfwk5/btsN8qvuOdB/Doe4NLmKkHYIYVDaDJGL40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pfwk5/btsN8qvuOdB/Doe4NLmKkHYIYVDaDJGL40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pfwk5/btsN8qvuOdB/Doe4NLmKkHYIYVDaDJGL40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpfwk5%2FbtsN8qvuOdB%2FDoe4NLmKkHYIYVDaDJGL40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;646&quot; height=&quot;203&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;source&amp;nbsp;yolov5/yolov5-env/bin/activate&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HRtGX/btsN6sVQp7E/YEZRTyKn79XNQyhEXu7Tbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HRtGX/btsN6sVQp7E/YEZRTyKn79XNQyhEXu7Tbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HRtGX/btsN6sVQp7E/YEZRTyKn79XNQyhEXu7Tbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHRtGX%2FbtsN6sVQp7E%2FYEZRTyKn79XNQyhEXu7Tbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;42&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;42&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RTV2A/btsN7fPRkrL/X0nSDrG5jifU6z29bXhby0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RTV2A/btsN7fPRkrL/X0nSDrG5jifU6z29bXhby0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RTV2A/btsN7fPRkrL/X0nSDrG5jifU6z29bXhby0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRTV2A%2FbtsN7fPRkrL%2FX0nSDrG5jifU6z29bXhby0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;553&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xvi4P/btsN7D37gqJ/PYLtKD5MVUV6vmEFbrxxc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xvi4P/btsN7D37gqJ/PYLtKD5MVUV6vmEFbrxxc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xvi4P/btsN7D37gqJ/PYLtKD5MVUV6vmEFbrxxc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxvi4P%2FbtsN7D37gqJ%2FPYLtKD5MVUV6vmEFbrxxc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;761&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #3c4043; text-align: start;&quot;&gt;1. 라즈베리파이의 Pictures 디렉토리에 있는 이미지 파일을 선택하여 YOLO 모델 탐지를 수행하고 그 결과 이미지를 화면에 출력하시오. &lt;/span&gt;&lt;span style=&quot;color: #3c4043; text-align: start;&quot;&gt;출력 화면에는 TrackBar 를 설치하여 Slide를 조정함에 따라 Confidence 값이 미달하는 객체는 탐지결과에서 제외되도록 구성하시오.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #3c4043; text-align: start;&quot;&gt;2. 동일한 기능을 WebCam 화면에도 적용하여 동영상 객체 인식을 구현하시오.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747895816230&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import cv2
import torch
import numpy as np
import os
from glob import glob

# Load YOLOv5s model (pretrained)
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
model.eval()

def detect_and_show_static(img_path):
    img = cv2.imread(img_path)
    if img is None:
        print(f&quot;Failed to load {img_path}&quot;)
        return

    window = 'Image Detection'
    cv2.namedWindow(window)
    cv2.createTrackbar('Confidence %', window, 50, 100, lambda x: None)

    while True:
        thresh = cv2.getTrackbarPos('Confidence %', window) / 100.0
        model.conf = thresh
        results = model(img)

        display = img.copy()
        for *box, conf, cls in results.xyxy[0].cpu().numpy():
            x1, y1, x2, y2 = map(int, box)
            label = f&quot;{model.names[int(cls)]}: {conf:.2f}&quot;
            cv2.rectangle(display, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.putText(display, label, (x1, y1 - 5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)

        cv2.imshow(window, display)
        key = cv2.waitKey(30) &amp;amp; 0xFF
        if key == 27:  # ESC
            break
        elif key == ord('n'):
            break

    cv2.destroyWindow(window)

img_files = glob(os.path.expanduser('~/Pictures/*.[jp][pn]g'))
for img_path in img_files:
    print(&quot;Showing:&quot;, img_path)
    detect_and_show_static(img_path)

def webcam_detection():
    window = 'WebCam Detection'
    cv2.namedWindow(window)
    cv2.createTrackbar('Confidence %', window, 50, 100, lambda x: None)

    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print(&quot;Webcam open failed&quot;)
        return

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        thresh = cv2.getTrackbarPos('Confidence %', window) / 100.0
        model.conf = thresh
        results = model(frame)

        for *box, conf, cls in results.xyxy[0].cpu().numpy():
            x1, y1, x2, y2 = map(int, box)
            label = f&quot;{model.names[int(cls)]}: {conf:.2f}&quot;
            cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)
            cv2.putText(frame, label, (x1, y1 - 5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)

        cv2.imshow(window, frame)
        if cv2.waitKey(1) &amp;amp; 0xFF == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

webcam_detection()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;753&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XqB3e/btsN9y092Qk/aq5ff1UGC3RuDlcn3GPIf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XqB3e/btsN9y092Qk/aq5ff1UGC3RuDlcn3GPIf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XqB3e/btsN9y092Qk/aq5ff1UGC3RuDlcn3GPIf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXqB3e%2FbtsN9y092Qk%2Faq5ff1UGC3RuDlcn3GPIf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1170&quot; height=&quot;753&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;753&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;753&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sayvp/btsN7Z6ZHPJ/7ykC8PqAgIIQ02GzknsAB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sayvp/btsN7Z6ZHPJ/7ykC8PqAgIIQ02GzknsAB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sayvp/btsN7Z6ZHPJ/7ykC8PqAgIIQ02GzknsAB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsayvp%2FbtsN7Z6ZHPJ%2F7ykC8PqAgIIQ02GzknsAB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1172&quot; height=&quot;753&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;753&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q61n1/btsN7F17XUB/78KSsVaMZFUiWRl3sVnZsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q61n1/btsN7F17XUB/78KSsVaMZFUiWRl3sVnZsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q61n1/btsN7F17XUB/78KSsVaMZFUiWRl3sVnZsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq61n1%2FbtsN7F17XUB%2F78KSsVaMZFUiWRl3sVnZsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;534&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;&lt;u&gt;3. 'Person' 이 감지될 경우 영상을 저장하고 계속 감시. (기타 객체 무시)&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747899373149&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import cv2
import torch
import numpy as np
import os
from glob import glob
from datetime import datetime

model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
model.eval()

SAVE_DIR = &quot;person_captures&quot;
os.makedirs(SAVE_DIR, exist_ok=True)

def detect_and_show_static(img_path):
    img = cv2.imread(img_path)
    if img is None:
        print(f&quot;Failed to load {img_path}&quot;)
        return

    window = 'Image Detection'
    cv2.namedWindow(window)
    cv2.createTrackbar('Confidence %', window, 50, 100, lambda x: None)

    while True:
        thresh = cv2.getTrackbarPos('Confidence %', window) / 100.0
        model.conf = thresh
        results = model(img)

        display = img.copy()
        for *box, conf, cls in results.xyxy[0].cpu().numpy():
            x1, y1, x2, y2 = map(int, box)
            label = f&quot;{model.names[int(cls)]}: {conf:.2f}&quot;
            color = (0, 255, 0) if int(cls) == 0 else (255, 0, 0)
            cv2.rectangle(display, (x1, y1), (x2, y2), color, 2)
            cv2.putText(display, label, (x1, y1 - 5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)

        cv2.imshow(window, display)
        key = cv2.waitKey(30) &amp;amp; 0xFF
        if key in (27, ord('n')):
            break

    cv2.destroyWindow(window)

img_files = glob(os.path.expanduser('~/Pictures/*.[jp][pn]g'))
for img_path in img_files:
    print(&quot;Showing:&quot;, img_path)
    detect_and_show_static(img_path)

def webcam_detection():
    window = 'WebCam Detection'
    cv2.namedWindow(window)
    cv2.createTrackbar('Confidence %', window, 50, 100, lambda x: None)

    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print(&quot;Webcam open failed&quot;)
        return

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        thresh = cv2.getTrackbarPos('Confidence %', window) / 100.0
        model.conf = thresh

        results = model(frame)
        detections = results.xyxy[0].cpu().numpy()

        person_detected = False
        for x1, y1, x2, y2, conf, cls in detections:
            cls = int(cls)
            label = f&quot;{model.names[cls]}: {conf:.2f}&quot;
            color = (255, 0, 0)
            cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2)
            cv2.putText(frame, label, (int(x1), int(y1) - 5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)

            if cls == 0:
                person_detected = True

        if person_detected:
            timestamp = datetime.now().strftime(&quot;%Y%m%d_%H%M%S_%f&quot;)
            save_path = os.path.join(SAVE_DIR, f&quot;person_{timestamp}.jpg&quot;)
            cv2.imwrite(save_path, frame)
            print(f&quot;??? Person detected! Saved to {save_path}&quot;)

        cv2.imshow(window, frame)
        if cv2.waitKey(1) &amp;amp; 0xFF == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

webcam_detection()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW0gfh/btsN7zt5ebE/LTMQQsmex9pBmJwttKmFI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW0gfh/btsN7zt5ebE/LTMQQsmex9pBmJwttKmFI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW0gfh/btsN7zt5ebE/LTMQQsmex9pBmJwttKmFI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW0gfh%2FbtsN7zt5ebE%2FLTMQQsmex9pBmJwttKmFI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;554&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WcOXV/btsN9A5E0U5/Rx8R7hTh6YcxKc4kiA4Kp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WcOXV/btsN9A5E0U5/Rx8R7hTh6YcxKc4kiA4Kp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WcOXV/btsN9A5E0U5/Rx8R7hTh6YcxKc4kiA4Kp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWcOXV%2FbtsN9A5E0U5%2FRx8R7hTh6YcxKc4kiA4Kp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;858&quot; height=&quot;610&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/506</guid>
      <comments>https://hotari.tistory.com/506#entry506comment</comments>
      <pubDate>Thu, 22 May 2025 16:38:03 +0900</pubDate>
    </item>
    <item>
      <title>4일차</title>
      <link>https://hotari.tistory.com/505</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.21&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djpRxM/btsN69UvZAC/6qwIYSg4KIkqNedYRVMfOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djpRxM/btsN69UvZAC/6qwIYSg4KIkqNedYRVMfOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djpRxM/btsN69UvZAC/6qwIYSg4KIkqNedYRVMfOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjpRxM%2FbtsN69UvZAC%2F6qwIYSg4KIkqNedYRVMfOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;822&quot; height=&quot;569&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html&quot;&gt;OpenCV: OpenCV-Python Tutorials&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;568&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6wuQa/btsN4sve4I4/Jf0PMEREckqxzjmA2m7GF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6wuQa/btsN4sve4I4/Jf0PMEREckqxzjmA2m7GF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6wuQa/btsN4sve4I4/Jf0PMEREckqxzjmA2m7GF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6wuQa%2FbtsN4sve4I4%2FJf0PMEREckqxzjmA2m7GF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;822&quot; height=&quot;568&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;568&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjcHOe/btsN4J4gxAy/lrCJnHCN7x5Lal6TI8kU31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjcHOe/btsN4J4gxAy/lrCJnHCN7x5Lal6TI8kU31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjcHOe/btsN4J4gxAy/lrCJnHCN7x5Lal6TI8kU31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjcHOe%2FbtsN4J4gxAy%2FlrCJnHCN7x5Lal6TI8kU31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;560&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDX9rX/btsN6ymR3Ug/RqRqVmNofKVIY2NeuTiQB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDX9rX/btsN6ymR3Ug/RqRqVmNofKVIY2NeuTiQB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDX9rX/btsN6ymR3Ug/RqRqVmNofKVIY2NeuTiQB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDX9rX%2FbtsN6ymR3Ug%2FRqRqVmNofKVIY2NeuTiQB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;803&quot; height=&quot;555&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m2PkN/btsN5Xm2oWH/h0c6PDKjutsIcz9Zy41iVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m2PkN/btsN5Xm2oWH/h0c6PDKjutsIcz9Zy41iVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m2PkN/btsN5Xm2oWH/h0c6PDKjutsIcz9Zy41iVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm2PkN%2FbtsN5Xm2oWH%2Fh0c6PDKjutsIcz9Zy41iVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;557&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WKf4v/btsN5R1kkVF/6fwEGr4wANtqZCKgosh5tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WKf4v/btsN5R1kkVF/6fwEGr4wANtqZCKgosh5tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WKf4v/btsN5R1kkVF/6fwEGr4wANtqZCKgosh5tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWKf4v%2FbtsN5R1kkVF%2F6fwEGr4wANtqZCKgosh5tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;560&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gzndv/btsN5fotZUz/V8sFxV7sRB9YUbJneT4H51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gzndv/btsN5fotZUz/V8sFxV7sRB9YUbJneT4H51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gzndv/btsN5fotZUz/V8sFxV7sRB9YUbJneT4H51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGzndv%2FbtsN5fotZUz%2FV8sFxV7sRB9YUbJneT4H51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;821&quot; height=&quot;721&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ArkmK/btsN5XAFVs9/tCQlXPS2QUFc1CiGWaLP9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ArkmK/btsN5XAFVs9/tCQlXPS2QUFc1CiGWaLP9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ArkmK/btsN5XAFVs9/tCQlXPS2QUFc1CiGWaLP9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FArkmK%2FbtsN5XAFVs9%2FtCQlXPS2QUFc1CiGWaLP9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;724&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYQThq/btsN4JjoChY/GOCzqhhEH6jZTbh7iGCwMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYQThq/btsN4JjoChY/GOCzqhhEH6jZTbh7iGCwMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYQThq/btsN4JjoChY/GOCzqhhEH6jZTbh7iGCwMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYQThq%2FbtsN4JjoChY%2FGOCzqhhEH6jZTbh7iGCwMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;716&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k0yVE/btsN4QXeeGu/e2JWnZIspK9iTA9gdAxOpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k0yVE/btsN4QXeeGu/e2JWnZIspK9iTA9gdAxOpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k0yVE/btsN4QXeeGu/e2JWnZIspK9iTA9gdAxOpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk0yVE%2FbtsN4QXeeGu%2Fe2JWnZIspK9iTA9gdAxOpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;718&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPmoJI/btsN6lvafgf/EudwTvFx1Kkq0mqUSL0Ly0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPmoJI/btsN6lvafgf/EudwTvFx1Kkq0mqUSL0Ly0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPmoJI/btsN6lvafgf/EudwTvFx1Kkq0mqUSL0Ly0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPmoJI%2FbtsN6lvafgf%2FEudwTvFx1Kkq0mqUSL0Ly0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;716&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PEJE2/btsN7cKYznF/heGX2UkK0cMpsCXgqXuZ41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PEJE2/btsN7cKYznF/heGX2UkK0cMpsCXgqXuZ41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PEJE2/btsN7cKYznF/heGX2UkK0cMpsCXgqXuZ41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPEJE2%2FbtsN7cKYznF%2FheGX2UkK0cMpsCXgqXuZ41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;900&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1747807646964&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import cv2

def nothing(x):
    pass

cap = cv2.VideoCapture(0)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

cv2.namedWindow('Filtered')

cv2.createTrackbar('Filter', 'Filtered', 0, 3, nothing)
cv2.createTrackbar('Kernel', 'Filtered', 1, 20, nothing)
cv2.createTrackbar('Thresh', 'Filtered', 127, 255, nothing)
cv2.createTrackbar('Canny Min', 'Filtered', 50, 255, nothing)
cv2.createTrackbar('Canny Max', 'Filtered', 150, 255, nothing)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    filter_type = cv2.getTrackbarPos('Filter', 'Filtered')
    kernel_size = cv2.getTrackbarPos('Kernel', 'Filtered')
    thresh_val = cv2.getTrackbarPos('Thresh', 'Filtered')
    canny_min = cv2.getTrackbarPos('Canny Min', 'Filtered')
    canny_max = cv2.getTrackbarPos('Canny Max', 'Filtered')

    if kernel_size % 2 == 0:
        kernel_size += 1
    if kernel_size &amp;lt; 1:
        kernel_size = 1

    result = frame.copy()

    if filter_type == 1:
        result = cv2.GaussianBlur(result, (kernel_size, kernel_size), 0)
    elif filter_type == 2:
        gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
        _, result = cv2.threshold(gray, thresh_val, 255, cv2.THRESH_BINARY)
    elif filter_type == 3:
        gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
        result = cv2.Canny(gray, canny_min, canny_max)

    cv2.imshow('Filtered', result)

    if cv2.waitKey(1) &amp;amp; 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg0wxJ/btsN7Cv1piX/Xg0PlE1JkCs9oanvLn7szk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg0wxJ/btsN7Cv1piX/Xg0PlE1JkCs9oanvLn7szk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg0wxJ/btsN7Cv1piX/Xg0PlE1JkCs9oanvLn7szk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg0wxJ%2FbtsN7Cv1piX%2FXg0PlE1JkCs9oanvLn7szk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;294&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z9lh9/btsN5qjxe47/THsYJ8V0u1OsXRegpq0lL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z9lh9/btsN5qjxe47/THsYJ8V0u1OsXRegpq0lL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z9lh9/btsN5qjxe47/THsYJ8V0u1OsXRegpq0lL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz9lh9%2FbtsN5qjxe47%2FTHsYJ8V0u1OsXRegpq0lL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;324&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZwpk9/btsN5vEW1OK/cGmMjp9vUwf4VZYM5sovaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZwpk9/btsN5vEW1OK/cGmMjp9vUwf4VZYM5sovaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZwpk9/btsN5vEW1OK/cGmMjp9vUwf4VZYM5sovaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZwpk9%2FbtsN5vEW1OK%2FcGmMjp9vUwf4VZYM5sovaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;896&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;896&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;903&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA2Gcm/btsN7aUltQO/lcA7GKABMhkFTkkJTft8DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA2Gcm/btsN7aUltQO/lcA7GKABMhkFTkkJTft8DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA2Gcm/btsN7aUltQO/lcA7GKABMhkFTkkJTft8DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA2Gcm%2FbtsN7aUltQO%2FlcA7GKABMhkFTkkJTft8DK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;903&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;903&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIqbXv/btsN7ZxHqKN/L9qdkPfA5io9fyMuA4Uo3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIqbXv/btsN7ZxHqKN/L9qdkPfA5io9fyMuA4Uo3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIqbXv/btsN7ZxHqKN/L9qdkPfA5io9fyMuA4Uo3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIqbXv%2FbtsN7ZxHqKN%2FL9qdkPfA5io9fyMuA4Uo3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;900&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TmNDl/btsN6YNc0gR/vQIviApu6xYGPJroTE2gSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TmNDl/btsN6YNc0gR/vQIviApu6xYGPJroTE2gSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TmNDl/btsN6YNc0gR/vQIviApu6xYGPJroTE2gSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTmNDl%2FbtsN6YNc0gR%2FvQIviApu6xYGPJroTE2gSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;893&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/505</guid>
      <comments>https://hotari.tistory.com/505#entry505comment</comments>
      <pubDate>Wed, 21 May 2025 16:51:31 +0900</pubDate>
    </item>
    <item>
      <title>3일차</title>
      <link>https://hotari.tistory.com/504</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.20&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k6DEs/btsN4oEMFoI/8Q9i4JRNdtkMx33GkZBeHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k6DEs/btsN4oEMFoI/8Q9i4JRNdtkMx33GkZBeHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k6DEs/btsN4oEMFoI/8Q9i4JRNdtkMx33GkZBeHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk6DEs%2FbtsN4oEMFoI%2F8Q9i4JRNdtkMx33GkZBeHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;429&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uZ5rR/btsN4QOzyy9/H3TwaY1KokG6s7fty9ecU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uZ5rR/btsN4QOzyy9/H3TwaY1KokG6s7fty9ecU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uZ5rR/btsN4QOzyy9/H3TwaY1KokG6s7fty9ecU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuZ5rR%2FbtsN4QOzyy9%2FH3TwaY1KokG6s7fty9ecU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;431&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8vNhN/btsN29onJ40/OkPSpbMJXfjO0XVGY0uXZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8vNhN/btsN29onJ40/OkPSpbMJXfjO0XVGY0uXZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8vNhN/btsN29onJ40/OkPSpbMJXfjO0XVGY0uXZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8vNhN%2FbtsN29onJ40%2FOkPSpbMJXfjO0XVGY0uXZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;428&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://remnant24c1.tistory.com/109#google_vignette&quot;&gt;Raspberry Pi 4(Bookworm)에서 WiringPi 설치해서 사용하기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sBaeP/btsN33BdLhw/iRL4Fs8emX4UQ26rdkGTKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sBaeP/btsN33BdLhw/iRL4Fs8emX4UQ26rdkGTKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sBaeP/btsN33BdLhw/iRL4Fs8emX4UQ26rdkGTKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsBaeP%2FbtsN33BdLhw%2FiRL4Fs8emX4UQ26rdkGTKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;965&quot; height=&quot;488&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSW1Gr/btsN4QHTslH/sLkChYjEQKEqnGSoOxWwSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSW1Gr/btsN4QHTslH/sLkChYjEQKEqnGSoOxWwSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSW1Gr/btsN4QHTslH/sLkChYjEQKEqnGSoOxWwSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSW1Gr%2FbtsN4QHTslH%2FsLkChYjEQKEqnGSoOxWwSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;969&quot; height=&quot;489&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;955&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eiTEOo/btsN4rV2c2u/xFqU9NhRL7FgXRbzPbs761/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eiTEOo/btsN4rV2c2u/xFqU9NhRL7FgXRbzPbs761/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eiTEOo/btsN4rV2c2u/xFqU9NhRL7FgXRbzPbs761/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeiTEOo%2FbtsN4rV2c2u%2FxFqU9NhRL7FgXRbzPbs761%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;955&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;955&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k4euz/btsN5eIumhz/nwZMQoUeb7Ff1j3yyZzPC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k4euz/btsN5eIumhz/nwZMQoUeb7Ff1j3yyZzPC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k4euz/btsN5eIumhz/nwZMQoUeb7Ff1j3yyZzPC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk4euz%2FbtsN5eIumhz%2FnwZMQoUeb7Ff1j3yyZzPC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;859&quot; height=&quot;609&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1V5XZ/btsN4FNdbB3/KvA0yJmcp4f7R5f5JZJ7U0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1V5XZ/btsN4FNdbB3/KvA0yJmcp4f7R5f5JZJ7U0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1V5XZ/btsN4FNdbB3/KvA0yJmcp4f7R5f5JZJ7U0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1V5XZ%2FbtsN4FNdbB3%2FKvA0yJmcp4f7R5f5JZJ7U0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;967&quot; height=&quot;631&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt-get install python3-opencv -y&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj36O0/btsN4K2uB3S/6coFkYDorPKyAs6ab0N7Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj36O0/btsN4K2uB3S/6coFkYDorPKyAs6ab0N7Fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj36O0/btsN4K2uB3S/6coFkYDorPKyAs6ab0N7Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj36O0%2FbtsN4K2uB3S%2F6coFkYDorPKyAs6ab0N7Fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;428&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdgmnn/btsN5nltNyz/6xXD9gaXi9HYi9qTvdXlI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdgmnn/btsN5nltNyz/6xXD9gaXi9HYi9qTvdXlI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdgmnn/btsN5nltNyz/6xXD9gaXi9HYi9qTvdXlI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdgmnn%2FbtsN5nltNyz%2F6xXD9gaXi9HYi9qTvdXlI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;887&quot; height=&quot;723&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CUqGl/btsN4GeYBw3/lCHDXjJJZTd0ODhwGWhHZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CUqGl/btsN4GeYBw3/lCHDXjJJZTd0ODhwGWhHZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CUqGl/btsN4GeYBw3/lCHDXjJJZTd0ODhwGWhHZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCUqGl%2FbtsN4GeYBw3%2FlCHDXjJJZTd0ODhwGWhHZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;748&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/504</guid>
      <comments>https://hotari.tistory.com/504#entry504comment</comments>
      <pubDate>Tue, 20 May 2025 16:52:30 +0900</pubDate>
    </item>
    <item>
      <title>2일차</title>
      <link>https://hotari.tistory.com/503</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.15&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqAeWP/btsNWTF7UmB/PoPB5X11VekspPdXS42bOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqAeWP/btsNWTF7UmB/PoPB5X11VekspPdXS42bOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqAeWP/btsNWTF7UmB/PoPB5X11VekspPdXS42bOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqAeWP%2FbtsNWTF7UmB%2FPoPB5X11VekspPdXS42bOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;649&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무선 LAN 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo nmtui&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo raspi-config&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1755&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qYZMG/btsNYUQ2Gy7/vsLwM7lYV8QLaKSOOljez0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qYZMG/btsNYUQ2Gy7/vsLwM7lYV8QLaKSOOljez0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qYZMG/btsNYUQ2Gy7/vsLwM7lYV8QLaKSOOljez0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqYZMG%2FbtsNYUQ2Gy7%2FvsLwM7lYV8QLaKSOOljez0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1755&quot; height=&quot;1018&quot; data-origin-width=&quot;1755&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;1017&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crdZb9/btsNZVWwE8S/e9vIhZvnkImOucFepMjWKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crdZb9/btsNZVWwE8S/e9vIhZvnkImOucFepMjWKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crdZb9/btsNZVWwE8S/e9vIhZvnkImOucFepMjWKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrdZb9%2FbtsNZVWwE8S%2Fe9vIhZvnkImOucFepMjWKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1754&quot; height=&quot;1017&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;1017&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cd /etc/NetworkManager/system-connections&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt-get update&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt-get install vim&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt-get install ibus ibus-hangul&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo apt-get install fonts-nanum fonts-unfonts-core&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/503</guid>
      <comments>https://hotari.tistory.com/503#entry503comment</comments>
      <pubDate>Thu, 15 May 2025 16:40:52 +0900</pubDate>
    </item>
    <item>
      <title>1일차</title>
      <link>https://hotari.tistory.com/502</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.14&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리 파이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 영국의 라즈베리 재단에서 학교와 개발도상국의 기초 컴퓨터 교육의 증진을 위해 개발한 싱글 보드 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 신용카드 크기의 초소형 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 뛰어난 그래픽 성능과 저렴한 가격&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CPU는 브로드컴 사의 BCM 시리즈를 주로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기존 데스크탑 PC와 비슷하게 키보드, 모니터 등의 주변기기와 연결해 사용 가능&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GJPe6/btsNWTkt29m/ywWdURzsDYDVHPbCRvYqM1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GJPe6/btsNWTkt29m/ywWdURzsDYDVHPbCRvYqM1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GJPe6/btsNWTkt29m/ywWdURzsDYDVHPbCRvYqM1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGJPe6%2FbtsNWTkt29m%2FywWdURzsDYDVHPbCRvYqM1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;199&quot; height=&quot;199&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 온전히 독립된 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다양하고 풍부한 공개 소프트웨어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주변 장치를 연결하기 쉬운 인터페이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 신용카드 크기로 소지하기에 부담이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 활용도가 높아 다양한 프로젝트 작품에 사용되고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MkTvB/btsNW2uL5lh/EEH4f2hMK8z9kBHZPvhGI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MkTvB/btsNW2uL5lh/EEH4f2hMK8z9kBHZPvhGI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MkTvB/btsNW2uL5lh/EEH4f2hMK8z9kBHZPvhGI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMkTvB%2FbtsNW2uL5lh%2FEEH4f2hMK8z9kBHZPvhGI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;673&quot; height=&quot;474&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egbfbJ/btsNWJvsRha/CBRkVv9Sfz2vndwrBHQdhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egbfbJ/btsNWJvsRha/CBRkVv9Sfz2vndwrBHQdhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egbfbJ/btsNWJvsRha/CBRkVv9Sfz2vndwrBHQdhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegbfbJ%2FbtsNWJvsRha%2FCBRkVv9Sfz2vndwrBHQdhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;491&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPv4 주소 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;928&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mmef2/btsNWOD4a2W/wrZqo1CIeTVI8DsjOboShK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mmef2/btsNWOD4a2W/wrZqo1CIeTVI8DsjOboShK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mmef2/btsNWOD4a2W/wrZqo1CIeTVI8DsjOboShK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmmef2%2FbtsNWOD4a2W%2FwrZqo1CIeTVI8DsjOboShK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1170&quot; height=&quot;928&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;928&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drmuyQ/btsNX6jMzoK/9rybnCOc1bT6BmQf8xTbNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drmuyQ/btsNX6jMzoK/9rybnCOc1bT6BmQf8xTbNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drmuyQ/btsNX6jMzoK/9rybnCOc1bT6BmQf8xTbNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrmuyQ%2FbtsNX6jMzoK%2F9rybnCOc1bT6BmQf8xTbNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;486&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cB8Lan/btsNXpYu8fN/TNKqJbg50tZsO9bh1TmZ6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cB8Lan/btsNXpYu8fN/TNKqJbg50tZsO9bh1TmZ6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cB8Lan/btsNXpYu8fN/TNKqJbg50tZsO9bh1TmZ6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcB8Lan%2FbtsNXpYu8fN%2FTNKqJbg50tZsO9bh1TmZ6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;404&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUdUXN/btsNV390nq5/E96jPuDKBG5chKhwDynhi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUdUXN/btsNV390nq5/E96jPuDKBG5chKhwDynhi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUdUXN/btsNV390nq5/E96jPuDKBG5chKhwDynhi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUdUXN%2FbtsNV390nq5%2FE96jPuDKBG5chKhwDynhi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;410&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXh1EF/btsNWNL8OCN/aQKzgVnkH3uXvA0QJFxtKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXh1EF/btsNWNL8OCN/aQKzgVnkH3uXvA0QJFxtKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXh1EF/btsNWNL8OCN/aQKzgVnkH3uXvA0QJFxtKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXh1EF%2FbtsNWNL8OCN%2FaQKzgVnkH3uXvA0QJFxtKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;651&quot; height=&quot;412&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lDkiI/btsNWjY2sMl/vtMloC9I9qErHMmsKJGyk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lDkiI/btsNWjY2sMl/vtMloC9I9qErHMmsKJGyk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lDkiI/btsNWjY2sMl/vtMloC9I9qErHMmsKJGyk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlDkiI%2FbtsNWjY2sMl%2FvtMloC9I9qErHMmsKJGyk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;410&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BMfT2/btsNV0yCK5E/enEKLzfvSNsYKjo5Mtg4uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BMfT2/btsNV0yCK5E/enEKLzfvSNsYKjo5Mtg4uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BMfT2/btsNV0yCK5E/enEKLzfvSNsYKjo5Mtg4uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBMfT2%2FbtsNV0yCK5E%2FenEKLzfvSNsYKjo5Mtg4uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;51&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;51&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1195&quot; data-origin-height=&quot;878&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHgb7X/btsNWcMn6oQ/6nt4ad5IcbdwWmj4yXnW1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHgb7X/btsNWcMn6oQ/6nt4ad5IcbdwWmj4yXnW1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHgb7X/btsNWcMn6oQ/6nt4ad5IcbdwWmj4yXnW1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHgb7X%2FbtsNWcMn6oQ%2F6nt4ad5IcbdwWmj4yXnW1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1195&quot; height=&quot;878&quot; data-origin-width=&quot;1195&quot; data-origin-height=&quot;878&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0VSau/btsNXTdHQdN/YmaXxGdIn6ORkoC8DGR7fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0VSau/btsNXTdHQdN/YmaXxGdIn6ORkoC8DGR7fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0VSau/btsNXTdHQdN/YmaXxGdIn6ORkoC8DGR7fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0VSau%2FbtsNXTdHQdN%2FYmaXxGdIn6ORkoC8DGR7fK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;879&quot; height=&quot;626&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ytzKF/btsNXYTEzCO/bMxPfI3WvwK5jdhejXhA1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ytzKF/btsNXYTEzCO/bMxPfI3WvwK5jdhejXhA1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ytzKF/btsNXYTEzCO/bMxPfI3WvwK5jdhejXhA1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FytzKF%2FbtsNXYTEzCO%2FbMxPfI3WvwK5jdhejXhA1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;877&quot; height=&quot;622&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1013&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKVnHL/btsNWoMyOoV/YJ5Ok0rXNpi6vCPSckO92k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKVnHL/btsNWoMyOoV/YJ5Ok0rXNpi6vCPSckO92k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKVnHL/btsNWoMyOoV/YJ5Ok0rXNpi6vCPSckO92k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKVnHL%2FbtsNWoMyOoV%2FYJ5Ok0rXNpi6vCPSckO92k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1760&quot; height=&quot;1013&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1013&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/SoC 시스템 반도체를 위한 온디바이스  AI</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/502</guid>
      <comments>https://hotari.tistory.com/502#entry502comment</comments>
      <pubDate>Wed, 14 May 2025 16:47:29 +0900</pubDate>
    </item>
    <item>
      <title>Mini Project1 - No Smoking Area Project (with YOLOv8)</title>
      <link>https://hotari.tistory.com/501</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.13&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;212&quot; data-start=&quot;187&quot; data-ke-size=&quot;size26&quot;&gt;  금연구역 흡연자 식별 프로젝트 개요&lt;/h2&gt;
&lt;h2 data-end=&quot;203&quot; data-start=&quot;190&quot; data-ke-size=&quot;size26&quot;&gt;  프로젝트 개요&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;373&quot; data-start=&quot;205&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;244&quot; data-start=&quot;205&quot;&gt;&lt;b&gt;프로젝트명&lt;/b&gt;: 금연구역 흡연자 실시간 탐지 및 웹 알림 시스템&lt;/li&gt;
&lt;li data-end=&quot;318&quot; data-start=&quot;245&quot;&gt;&lt;b&gt;목표&lt;/b&gt;: CCTV 또는 웹캠으로 입력되는 영상에서 &lt;b&gt;흡연 행위 탐지 후 웹 서버를 통해 경고 및 저장&lt;/b&gt;하는 시스템 구축&lt;/li&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;319&quot;&gt;&lt;b&gt;기술요소&lt;/b&gt;: YOLOv8 + Flask + OpenCV 기반 영상 스트리밍 및 객체 탐지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;378&quot; data-start=&quot;375&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;391&quot; data-start=&quot;380&quot; data-ke-size=&quot;size26&quot;&gt; ️ 실행 흐름 요약&lt;/h2&gt;
&lt;pre id=&quot;code_1747116399730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[웹캠 영상 수신]
        &amp;darr;
[YOLOv8로 person/cigarette 탐지]
        &amp;darr;
[담배가 사람 박스 내부? &amp;rarr; YES]
        &amp;darr;
[30 프레임 이상 유지? &amp;rarr; YES]
        &amp;darr;
[1회 카운트 증가 + 이미지 저장 + 빨간 화면 + 경고 문구 출력]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-end=&quot;391&quot; data-start=&quot;380&quot; data-ke-size=&quot;size26&quot;&gt;  주요 기능&lt;/h2&gt;
&lt;div&gt;기능설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;688&quot; data-start=&quot;393&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;688&quot; data-start=&quot;421&quot;&gt;
&lt;tr data-end=&quot;479&quot; data-start=&quot;421&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;432&quot; data-start=&quot;421&quot;&gt;  객체 탐지&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;479&quot; data-start=&quot;432&quot;&gt;person, cigarette 클래스 YOLOv8 모델로 실시간 탐지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;529&quot; data-start=&quot;480&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;491&quot; data-start=&quot;480&quot;&gt;  포함 판단&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;529&quot; data-start=&quot;491&quot;&gt;담배 박스가 사람 박스 안에 포함되면 &lt;b&gt;흡연 행위로 판단&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;582&quot; data-start=&quot;530&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;543&quot; data-start=&quot;530&quot;&gt; ️ 프레임 저장&lt;/td&gt;
&lt;td data-end=&quot;582&quot; data-start=&quot;543&quot; data-col-size=&quot;sm&quot;&gt;탐지된 흡연 이미지 자동 저장 (폴더 및 static 디렉토리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;636&quot; data-start=&quot;583&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;594&quot; data-start=&quot;583&quot;&gt;  경고 출력&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;636&quot; data-start=&quot;594&quot;&gt;&quot;Stop Smoking Please.&quot; 문구 및 빨간 오버레이 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;688&quot; data-start=&quot;637&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;647&quot; data-start=&quot;637&quot;&gt;  웹 제공&lt;/td&gt;
&lt;td data-end=&quot;688&quot; data-start=&quot;647&quot; data-col-size=&quot;sm&quot;&gt;Flask 서버에서 실시간 스트리밍 + 최근 이미지 확인 UI 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 83px;&quot; border=&quot;1&quot; data-end=&quot;1718&quot; data-start=&quot;1449&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1718&quot; data-start=&quot;1505&quot;&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1561&quot; data-start=&quot;1505&quot;&gt;
&lt;td style=&quot;height: 21px; width: 23.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1517&quot; data-start=&quot;1505&quot;&gt;이미지 저장 조건&lt;/td&gt;
&lt;td style=&quot;height: 21px; width: 76.6279%;&quot; data-end=&quot;1561&quot; data-start=&quot;1532&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;지속 시간 조건 만족 시 한 번만 저장&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1612&quot; data-start=&quot;1562&quot;&gt;
&lt;td style=&quot;height: 21px; width: 23.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1573&quot; data-start=&quot;1562&quot;&gt;중복 저장 방지&lt;/td&gt;
&lt;td style=&quot;height: 21px; width: 76.6279%;&quot; data-end=&quot;1612&quot; data-start=&quot;1578&quot; data-col-size=&quot;sm&quot;&gt;✅ is_counted 플래그로 1회 저장 후 무시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1674&quot; data-start=&quot;1613&quot;&gt;
&lt;td style=&quot;height: 21px; width: 23.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1625&quot; data-start=&quot;1613&quot;&gt;프레임 기반 조건&lt;/td&gt;
&lt;td style=&quot;height: 21px; width: 76.6279%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1674&quot; data-start=&quot;1630&quot;&gt;✅ SMOKE_DETECT_THRESHOLD (기본 30프레임) 도입&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot; data-end=&quot;1718&quot; data-start=&quot;1675&quot;&gt;
&lt;td style=&quot;height: 20px; width: 23.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1687&quot; data-start=&quot;1675&quot;&gt;탐지 시 오버레이&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 76.6279%;&quot; data-end=&quot;1718&quot; data-start=&quot;1692&quot; data-col-size=&quot;sm&quot;&gt;동일하게 붉은 배경 + 텍스트 출력 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;693&quot; data-start=&quot;690&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;707&quot; data-start=&quot;695&quot; data-ke-size=&quot;size26&quot;&gt; ️ 기술 구성&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;항목사용 기술
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;974&quot; data-start=&quot;709&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;974&quot; data-start=&quot;745&quot;&gt;
&lt;tr data-end=&quot;761&quot; data-start=&quot;745&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;752&quot; data-start=&quot;745&quot;&gt;웹 서버&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;761&quot; data-start=&quot;752&quot;&gt;Flask&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;832&quot; data-start=&quot;762&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;769&quot; data-start=&quot;762&quot;&gt;영상처리&lt;/td&gt;
&lt;td data-end=&quot;832&quot; data-start=&quot;769&quot; data-col-size=&quot;md&quot;&gt;OpenCV (cv2.VideoCapture, cv2.rectangle, cv2.imwrite)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;872&quot; data-start=&quot;833&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;840&quot; data-start=&quot;833&quot;&gt;객체탐지&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;872&quot; data-start=&quot;840&quot;&gt;YOLOv8 (ultralytics 라이브러리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;926&quot; data-start=&quot;873&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;884&quot; data-start=&quot;873&quot;&gt;실시간 스트리밍&lt;/td&gt;
&lt;td data-end=&quot;926&quot; data-start=&quot;884&quot; data-col-size=&quot;md&quot;&gt;multipart/x-mixed-replace MIME 타입 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;974&quot; data-start=&quot;927&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;936&quot; data-start=&quot;927&quot;&gt;UI 템플릿&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;974&quot; data-start=&quot;936&quot;&gt;index.html (최근 감지 이미지와 흡연자 수 표시)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;366&quot; data-start=&quot;363&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;383&quot; data-start=&quot;368&quot; data-ke-size=&quot;size23&quot;&gt;  data.yaml (Roboflow 기반) 분석&lt;/h3&gt;
&lt;h3 data-end=&quot;623&quot; data-start=&quot;608&quot; data-ke-size=&quot;size23&quot;&gt;  주요 요소 해설&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;항목설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;873&quot; data-start=&quot;625&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;873&quot; data-start=&quot;653&quot;&gt;
&lt;tr data-end=&quot;727&quot; data-start=&quot;653&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;678&quot; data-start=&quot;653&quot;&gt;train, val, test&lt;/td&gt;
&lt;td data-end=&quot;727&quot; data-start=&quot;678&quot; data-col-size=&quot;md&quot;&gt;각각의 이미지 경로 지정. 절대경로를 사용하여 Windows PC 환경에서 구성됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;774&quot; data-start=&quot;728&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;735&quot; data-start=&quot;728&quot;&gt;nc&lt;/td&gt;
&lt;td data-end=&quot;774&quot; data-start=&quot;735&quot; data-col-size=&quot;md&quot;&gt;클래스 수: 2개 (cigarette, person)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;799&quot; data-start=&quot;775&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;785&quot; data-start=&quot;775&quot;&gt;names&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;799&quot; data-start=&quot;785&quot;&gt;클래스 이름 리스트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;873&quot; data-start=&quot;800&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;813&quot; data-start=&quot;800&quot;&gt;roboflow&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;873&quot; data-start=&quot;813&quot;&gt;Roboflow에서 자동으로 추가된 메타데이터 정보. 데이터셋의 출처, 프로젝트명, 라이선스 등 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;383&quot; data-start=&quot;368&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;383&quot; data-start=&quot;368&quot; data-ke-size=&quot;size23&quot;&gt;  학습 과정 개요&lt;/h3&gt;
&lt;h4 data-end=&quot;399&quot; data-start=&quot;385&quot; data-ke-size=&quot;size20&quot;&gt;✅ 데이터셋 구성&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;항목내용
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;661&quot; data-start=&quot;400&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;661&quot; data-start=&quot;428&quot;&gt;
&lt;tr data-end=&quot;459&quot; data-start=&quot;428&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;434&quot; data-start=&quot;428&quot;&gt;클래스&lt;/td&gt;
&lt;td data-end=&quot;459&quot; data-start=&quot;434&quot; data-col-size=&quot;sm&quot;&gt;person, cigarette&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;513&quot; data-start=&quot;460&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;471&quot; data-start=&quot;460&quot;&gt;총 인스턴스 수&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;513&quot; data-start=&quot;471&quot;&gt;person: 약 6,800개 / cigarette: 약 6,400개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;562&quot; data-start=&quot;514&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;528&quot; data-start=&quot;514&quot;&gt;이미지 내 객체 위치&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;562&quot; data-start=&quot;528&quot;&gt;대부분 중앙 중심에 분포 (center bias 존재)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;617&quot; data-start=&quot;563&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;575&quot; data-start=&quot;563&quot;&gt;바운딩 박스 크기&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;617&quot; data-start=&quot;575&quot;&gt;cigarette는 작고 compact, person은 상대적으로 큼&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;661&quot; data-start=&quot;618&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;631&quot; data-start=&quot;618&quot;&gt;데이터 불균형 여부&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;661&quot; data-start=&quot;631&quot;&gt;심각한 imbalance는 아님 (비슷한 수준)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;684&quot; data-start=&quot;663&quot; data-ke-size=&quot;size20&quot;&gt;  바운딩 박스 통계 시각화&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;771&quot; data-start=&quot;685&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;712&quot; data-start=&quot;685&quot;&gt;cigarette: 소형 객체, 중앙 밀집&lt;/li&gt;
&lt;li data-end=&quot;735&quot; data-start=&quot;713&quot;&gt;person: 다양한 크기와 위치&lt;/li&gt;
&lt;li data-end=&quot;771&quot; data-start=&quot;736&quot;&gt;너비-높이 분포에서 cigarette는 작은 범위에 집중&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;776&quot; data-start=&quot;773&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;793&quot; data-start=&quot;778&quot; data-ke-size=&quot;size23&quot;&gt;  학습 결과 분석&lt;/h3&gt;
&lt;h4 data-end=&quot;808&quot; data-start=&quot;795&quot; data-ke-size=&quot;size20&quot;&gt;  성능 지표&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;957&quot; data-start=&quot;809&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;856&quot; data-start=&quot;809&quot;&gt;&lt;b&gt;F1 최적 confidence&lt;/b&gt;: 0.308 (F1 score = 0.77)&lt;/li&gt;
&lt;li data-end=&quot;912&quot; data-start=&quot;857&quot;&gt;&lt;b&gt;Precision 최적 confidence&lt;/b&gt;: 0.874 (Precision = 1.00)&lt;/li&gt;
&lt;li data-end=&quot;957&quot; data-start=&quot;913&quot;&gt;&lt;b&gt;Recall 최고점&lt;/b&gt;: 0.90 (at confidence = 0.0)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;991&quot; data-start=&quot;959&quot; data-ke-size=&quot;size20&quot;&gt;  학습 곡선 분석 (results.png)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djERdi/btsNVjXK3RY/msKEaQCk02iGK5wNod4jF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djERdi/btsNVjXK3RY/msKEaQCk02iGK5wNod4jF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djERdi/btsNVjXK3RY/msKEaQCk02iGK5wNod4jF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjERdi%2FbtsNVjXK3RY%2FmsKEaQCk02iGK5wNod4jF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;1200&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;항목경향
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1259&quot; data-start=&quot;992&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1259&quot; data-start=&quot;1020&quot;&gt;
&lt;tr data-end=&quot;1073&quot; data-start=&quot;1020&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1063&quot; data-start=&quot;1020&quot;&gt;train/box_loss, cls_loss, dfl_loss&lt;/td&gt;
&lt;td data-end=&quot;1073&quot; data-start=&quot;1063&quot; data-col-size=&quot;md&quot;&gt;안정적 감소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1131&quot; data-start=&quot;1074&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1107&quot; data-start=&quot;1074&quot;&gt;val/cls_loss, val/dfl_loss&lt;/td&gt;
&lt;td data-end=&quot;1131&quot; data-start=&quot;1107&quot; data-col-size=&quot;md&quot;&gt;일부 노이즈 존재, 전체적 감소 추세&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1201&quot; data-start=&quot;1132&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1156&quot; data-start=&quot;1132&quot;&gt;precision, recall&lt;/td&gt;
&lt;td data-end=&quot;1201&quot; data-start=&quot;1156&quot; data-col-size=&quot;md&quot;&gt;점진적 상승 (최종 Precision ~0.78, Recall ~0.75)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1228&quot; data-start=&quot;1202&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1214&quot; data-start=&quot;1202&quot;&gt;mAP@0.5&lt;/td&gt;
&lt;td data-end=&quot;1228&quot; data-start=&quot;1214&quot; data-col-size=&quot;md&quot;&gt;약 0.775 도달&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1259&quot; data-start=&quot;1229&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1246&quot; data-start=&quot;1229&quot;&gt;mAP@0.5:0.95&lt;/td&gt;
&lt;td data-end=&quot;1259&quot; data-start=&quot;1246&quot; data-col-size=&quot;md&quot;&gt;약 0.32 도달&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;1278&quot; data-start=&quot;1261&quot; data-ke-size=&quot;size20&quot;&gt;  문제점 및 개선점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1384&quot; data-start=&quot;1279&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1335&quot; data-start=&quot;1279&quot;&gt;cigarette 클래스에서 Precision/Recall 낮음 &amp;rarr; 작은 객체 탐지 강화 필요&lt;/li&gt;
&lt;li data-end=&quot;1384&quot; data-start=&quot;1336&quot;&gt;중앙 밀집 데이터 특성으로 인해 실제 응용시 오탐 가능성 존재 &amp;rarr; 배경 다양화 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1389&quot; data-start=&quot;1386&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1415&quot; data-start=&quot;1391&quot; data-ke-size=&quot;size23&quot;&gt;  모델 응용: 실시간 경고 시스템&lt;/h3&gt;
&lt;h4 data-end=&quot;1430&quot; data-start=&quot;1417&quot; data-ke-size=&quot;size20&quot;&gt;  동작 방식&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1567&quot; data-start=&quot;1431&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1452&quot; data-start=&quot;1431&quot;&gt;실시간 웹캠 또는 영상 스트림 처리&lt;/li&gt;
&lt;li data-end=&quot;1567&quot; data-start=&quot;1453&quot;&gt;객체 탐지 수행 후, 담배 bounding box가 사람 bounding box에 &lt;b&gt;완전히 포함&lt;/b&gt;되면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1567&quot; data-start=&quot;1517&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1544&quot; data-start=&quot;1517&quot;&gt;&quot;금연구역입니다. 나가주세요&quot; 문구 화면 출력&lt;/li&gt;
&lt;li data-end=&quot;1567&quot; data-start=&quot;1547&quot;&gt;(선택) TTS로 음성 경고 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1582&quot; data-start=&quot;1569&quot; data-ke-size=&quot;size20&quot;&gt;  사용 코드&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1777&quot; data-start=&quot;1583&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1616&quot; data-start=&quot;1583&quot;&gt;YOLO('best.pt') 로 커스텀 모델 불러오기&lt;/li&gt;
&lt;li data-end=&quot;1648&quot; data-start=&quot;1617&quot;&gt;OpenCV VideoCapture로 프레임 추출&lt;/li&gt;
&lt;li data-end=&quot;1698&quot; data-start=&quot;1649&quot;&gt;box.xyxy, box.cls, results.names를 활용한 후처리&lt;/li&gt;
&lt;li data-end=&quot;1749&quot; data-start=&quot;1699&quot;&gt;포함 조건: person_box가 cigarette_box를 완전히 포함할 경우&lt;/li&gt;
&lt;li data-end=&quot;1777&quot; data-start=&quot;1750&quot;&gt;cv2.putText()로 경고 문구 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1782&quot; data-start=&quot;1779&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1799&quot; data-start=&quot;1784&quot; data-ke-size=&quot;size23&quot;&gt;  향후 개선 방향&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1968&quot; data-start=&quot;1801&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1840&quot; data-start=&quot;1801&quot;&gt;  데이터 증강: Mosaic, CutMix, Copy-Paste&lt;/li&gt;
&lt;li data-end=&quot;1887&quot; data-start=&quot;1841&quot;&gt;  소형 객체 특화 백본 적용 (YOLO-NAS, EfficientDet 등)&lt;/li&gt;
&lt;li data-end=&quot;1913&quot; data-start=&quot;1888&quot;&gt;  CCTV 연동 및 경고 시스템 자동화&lt;/li&gt;
&lt;li data-end=&quot;1968&quot; data-start=&quot;1914&quot;&gt;  TTS 및 알람 시스템 연동 (ESP32, Raspberry Pi로 IoT 연동도 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;118&quot; data-start=&quot;70&quot; data-ke-size=&quot;size26&quot;&gt;  1. F1-Confidence Curve 분석 (F1_curve.png)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pg2Yy/btsNTBS9kfH/xgkKkwzNbP0wab5Go3tF21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pg2Yy/btsNTBS9kfH/xgkKkwzNbP0wab5Go3tF21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pg2Yy/btsNTBS9kfH/xgkKkwzNbP0wab5Go3tF21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpg2Yy%2FbtsNTBS9kfH%2FxgkKkwzNbP0wab5Go3tF21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;1500&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;388&quot; data-start=&quot;119&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;167&quot; data-start=&quot;119&quot;&gt;&lt;b&gt;전체 최고 F1 score = 0.77 @ confidence = 0.308&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;276&quot; data-start=&quot;168&quot;&gt;클래스별 F1 성능:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;276&quot; data-start=&quot;184&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;227&quot; data-start=&quot;184&quot;&gt;person: 전체적으로 높은 F1-score 유지 (최고 약 0.9)&lt;/li&gt;
&lt;li data-end=&quot;276&quot; data-start=&quot;230&quot;&gt;cigarette: F1-score가 낮고 변동폭이 큼 (최고 약 0.65)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;388&quot; data-start=&quot;277&quot;&gt;&lt;b&gt;해석&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;388&quot; data-start=&quot;289&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;342&quot; data-start=&quot;289&quot;&gt;모델은 사람(person)을 잘 탐지하지만 담배(cigarette) 탐지는 상대적으로 어려움&lt;/li&gt;
&lt;li data-end=&quot;388&quot; data-start=&quot;345&quot;&gt;가장 이상적인 confidence threshold는 &lt;b&gt;약 0.308&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;393&quot; data-start=&quot;390&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;449&quot; data-start=&quot;395&quot; data-ke-size=&quot;size26&quot;&gt;  2. Precision-Confidence Curve 분석 (P_curve.png)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/80HSi/btsNUNSxeDg/0lLdktLU8Y0bzzPAGoKilk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/80HSi/btsNUNSxeDg/0lLdktLU8Y0bzzPAGoKilk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/80HSi/btsNUNSxeDg/0lLdktLU8Y0bzzPAGoKilk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F80HSi%2FbtsNUNSxeDg%2F0lLdktLU8Y0bzzPAGoKilk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;1500&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;712&quot; data-start=&quot;450&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;495&quot; data-start=&quot;450&quot;&gt;&lt;b&gt;전체 precision = 1.0 @ confidence = 0.874&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;496&quot;&gt;클래스별 precision:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;615&quot; data-start=&quot;516&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;552&quot; data-start=&quot;516&quot;&gt;person: 높은 precision 유지 (0.9 이상)&lt;/li&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;555&quot;&gt;cigarette: 낮은 confidence에선 precision 저조, 0.8 부근에서 최댓값 근접&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;712&quot; data-start=&quot;616&quot;&gt;&lt;b&gt;해석&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;712&quot; data-start=&quot;628&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;660&quot; data-start=&quot;628&quot;&gt;높은 confidence일수록 precision 향상됨&lt;/li&gt;
&lt;li data-end=&quot;712&quot; data-start=&quot;663&quot;&gt;cigarette 클래스는 오탐지 비율이 높음 (false positive 많음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;717&quot; data-start=&quot;714&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;770&quot; data-start=&quot;719&quot; data-ke-size=&quot;size26&quot;&gt;  3. Recall-Confidence Curve 분석 (R_curve.png)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6limZ/btsNVikgvux/XZDYyIDpAV7CRczDcr4Yz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6limZ/btsNVikgvux/XZDYyIDpAV7CRczDcr4Yz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6limZ/btsNVikgvux/XZDYyIDpAV7CRczDcr4Yz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6limZ%2FbtsNVikgvux%2FXZDYyIDpAV7CRczDcr4Yz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;1500&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;1500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1052&quot; data-start=&quot;771&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;771&quot;&gt;&lt;b&gt;전체 recall = 0.90 @ confidence = 0.000&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;844&quot; data-start=&quot;815&quot;&gt;confidence가 증가할수록 recall 감소&lt;/li&gt;
&lt;li data-end=&quot;879&quot; data-start=&quot;845&quot;&gt;person: 높은 recall 유지 (0.85 이상)&lt;/li&gt;
&lt;li data-end=&quot;924&quot; data-start=&quot;880&quot;&gt;cigarette: confidence 0.3 이상에서 recall 급감&lt;/li&gt;
&lt;li data-end=&quot;1052&quot; data-start=&quot;925&quot;&gt;&lt;b&gt;해석&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1052&quot; data-start=&quot;937&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1003&quot; data-start=&quot;937&quot;&gt;낮은 confidence에서도 많은 객체 탐지됨 (recall &amp;uarr;) &amp;rarr; false positive 증가 가능성 있음&lt;/li&gt;
&lt;li data-end=&quot;1052&quot; data-start=&quot;1006&quot;&gt;cigarette은 recall과 precision을 균형 있게 잡기 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1057&quot; data-start=&quot;1054&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1089&quot; data-start=&quot;1059&quot; data-ke-size=&quot;size26&quot;&gt;  4. 학습 곡선 (results.png)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r7vwj/btsNUb7uctW/YKnSE9oVlgPDglZwxuoHFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r7vwj/btsNUb7uctW/YKnSE9oVlgPDglZwxuoHFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r7vwj/btsNUb7uctW/YKnSE9oVlgPDglZwxuoHFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr7vwj%2FbtsNUb7uctW%2FYKnSE9oVlgPDglZwxuoHFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;1200&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1559&quot; data-start=&quot;1090&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1172&quot; data-start=&quot;1090&quot;&gt;Training 손실 감소:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1172&quot; data-start=&quot;1114&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1172&quot; data-start=&quot;1114&quot;&gt;box_loss, cls_loss, dfl_loss 모두 꾸준히 감소 &amp;rarr; 학습은 잘 진행됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1276&quot; data-start=&quot;1173&quot;&gt;Validation 손실:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1276&quot; data-start=&quot;1196&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1222&quot; data-start=&quot;1196&quot;&gt;val_cls_loss: 안정적으로 감소&lt;/li&gt;
&lt;li data-end=&quot;1276&quot; data-start=&quot;1225&quot;&gt;val_box_loss, val_dfl_loss: 비교적 노이즈 많고 다소 불안정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1417&quot; data-start=&quot;1277&quot;&gt;성능 지표:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1417&quot; data-start=&quot;1292&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1327&quot; data-start=&quot;1292&quot;&gt;Precision(B): 점진적으로 상승 (약 0.78)&lt;/li&gt;
&lt;li data-end=&quot;1361&quot; data-start=&quot;1330&quot;&gt;Recall(B): 0.60 &amp;rarr; 0.75까지 향상&lt;/li&gt;
&lt;li data-end=&quot;1388&quot; data-start=&quot;1364&quot;&gt;mAP50(B): 약 0.775 도달&lt;/li&gt;
&lt;li data-end=&quot;1417&quot; data-start=&quot;1391&quot;&gt;mAP50-95(B): 약 0.32 도달&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1559&quot; data-start=&quot;1418&quot;&gt;&lt;b&gt;해석&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1559&quot; data-start=&quot;1430&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1472&quot; data-start=&quot;1430&quot;&gt;전반적으로 &lt;b&gt;precision, recall, mAP 모두 향상 중&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1516&quot; data-start=&quot;1475&quot;&gt;validation loss에서 약간의 노이즈는 있지만 추세는 안정적임&lt;/li&gt;
&lt;li data-end=&quot;1559&quot; data-start=&quot;1519&quot;&gt;모델 성능은 &lt;b&gt;양호&lt;/b&gt;하지만 cigarette 클래스 개선 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1564&quot; data-start=&quot;1561&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1576&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size26&quot;&gt;✅ 종합 평가&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;항목평가
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1923&quot; data-start=&quot;1578&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1923&quot; data-start=&quot;1606&quot;&gt;
&lt;tr data-end=&quot;1666&quot; data-start=&quot;1606&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1629&quot; data-start=&quot;1606&quot;&gt;&lt;b&gt;사람(person) 탐지 성능&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1666&quot; data-start=&quot;1629&quot; data-col-size=&quot;md&quot;&gt;매우 우수 (Precision/Recall/F1 모두 높음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1732&quot; data-start=&quot;1667&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1693&quot; data-start=&quot;1667&quot;&gt;&lt;b&gt;담배(cigarette) 탐지 성능&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1732&quot; data-start=&quot;1693&quot; data-col-size=&quot;md&quot;&gt;낮음 (precision, recall, F1 모두 낮고 민감)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1785&quot; data-start=&quot;1733&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1755&quot; data-start=&quot;1733&quot;&gt;&lt;b&gt;F1 최적 threshold&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;1785&quot; data-start=&quot;1755&quot;&gt;0.308 (전체 F1 score 최대화 지점)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1834&quot; data-start=&quot;1786&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1805&quot; data-start=&quot;1786&quot;&gt;&lt;b&gt;최종 Precision&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1834&quot; data-start=&quot;1805&quot; data-col-size=&quot;md&quot;&gt;1.00 (confidence 0.874에서)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1923&quot; data-start=&quot;1835&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1851&quot; data-start=&quot;1835&quot;&gt;&lt;b&gt;모델 개선 포인트&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1923&quot; data-start=&quot;1851&quot; data-col-size=&quot;md&quot;&gt;담배 객체 탐지 데이터 추가 학습 / class imbalance 해결 / hard negative mining 적용 권장&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cU6R78/btsNUV33GXJ/ZKBrAgIqhvFcDpSSOtm3v0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cU6R78/btsNUV33GXJ/ZKBrAgIqhvFcDpSSOtm3v0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cU6R78/btsNUV33GXJ/ZKBrAgIqhvFcDpSSOtm3v0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcU6R78%2FbtsNUV33GXJ%2FZKBrAgIqhvFcDpSSOtm3v0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;1600&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;153&quot; data-start=&quot;116&quot; data-ke-size=&quot;size26&quot;&gt;  1. 클래스별 인스턴스 수 분포 (좌측 상단 바 그래프)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;374&quot; data-start=&quot;154&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;213&quot; data-start=&quot;154&quot;&gt;&lt;b&gt;클래스:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;213&quot; data-start=&quot;167&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;190&quot; data-start=&quot;167&quot;&gt;cigarette: 약 6,400개&lt;/li&gt;
&lt;li data-end=&quot;213&quot; data-start=&quot;193&quot;&gt;person: 약 6,800개&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;374&quot; data-start=&quot;214&quot;&gt;&lt;b&gt;해석:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;374&quot; data-start=&quot;226&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;286&quot; data-start=&quot;226&quot;&gt;두 클래스 간 데이터 수는 비교적 균형적이나, 약간의 불균형은 존재함 (person이 조금 더 많음)&lt;/li&gt;
&lt;li data-end=&quot;374&quot; data-start=&quot;289&quot;&gt;class imbalance 문제가 &lt;b&gt;심각하진 않음&lt;/b&gt; &amp;rarr; 모델 학습에 큰 영향을 주진 않지만 정밀한 탐지를 위해 담배 클래스 추가 확보 고려 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;379&quot; data-start=&quot;376&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;408&quot; data-start=&quot;381&quot; data-ke-size=&quot;size26&quot;&gt;  2. 바운딩 박스 시각화 (우측 상단)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;661&quot; data-start=&quot;409&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;447&quot; data-start=&quot;409&quot;&gt;이미지 전체에서 각 클래스의 바운딩 박스 위치를 선으로 표시한 것&lt;/li&gt;
&lt;li data-end=&quot;488&quot; data-start=&quot;448&quot;&gt;cigarette: 진한 파란색 / person: 밝은 하늘색&lt;/li&gt;
&lt;li data-end=&quot;661&quot; data-start=&quot;489&quot;&gt;&lt;b&gt;해석:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;661&quot; data-start=&quot;501&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;526&quot; data-start=&quot;501&quot;&gt;대부분의 객체는 &lt;b&gt;이미지 중앙에 위치&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;567&quot; data-start=&quot;529&quot;&gt;cigarette 클래스는 크기가 작고 상대적으로 중앙에 몰림&lt;/li&gt;
&lt;li data-end=&quot;603&quot; data-start=&quot;570&quot;&gt;person 클래스는 크고 화면 전체에 고르게 분포됨&lt;/li&gt;
&lt;li data-end=&quot;661&quot; data-start=&quot;606&quot;&gt;이 차이 때문에 모델이 cigarette을 잘 탐지하지 못할 수 있음 (작은 객체 탐지 어려움)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;666&quot; data-start=&quot;663&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;705&quot; data-start=&quot;668&quot; data-ke-size=&quot;size26&quot;&gt;  3. 중심 좌표 분포 (좌측 하단, x-y 분포 히트맵)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;888&quot; data-start=&quot;706&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;734&quot; data-start=&quot;706&quot;&gt;바운딩 박스 중심의 (x, y) 좌표 히트맵&lt;/li&gt;
&lt;li data-end=&quot;772&quot; data-start=&quot;735&quot;&gt;중심은 대체로 이미지 중앙 근처 (0.5, 0.5)에 밀집됨&lt;/li&gt;
&lt;li data-end=&quot;888&quot; data-start=&quot;773&quot;&gt;&lt;b&gt;해석:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;888&quot; data-start=&quot;785&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;840&quot; data-start=&quot;785&quot;&gt;데이터셋이 중앙에 객체가 위치한 경우가 많음 &amp;rarr; &lt;b&gt;중심성 편향(Center Bias)&lt;/b&gt; 존재&lt;/li&gt;
&lt;li data-end=&quot;888&quot; data-start=&quot;843&quot;&gt;이는 모델의 일반화 성능에 영향을 줄 수 있음 (모델이 중심에만 집중하게 됨)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;893&quot; data-start=&quot;890&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;935&quot; data-start=&quot;895&quot; data-ke-size=&quot;size26&quot;&gt;  4. 크기 분포 (우측 하단, width-height 히트맵)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1177&quot; data-start=&quot;936&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;955&quot; data-start=&quot;936&quot;&gt;바운딩 박스의 너비와 높이 분포&lt;/li&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;956&quot;&gt;대부분의 객체는 &lt;b&gt;(width, height) &amp;asymp; (0.1&lt;s&gt;0.3, 0.1&lt;/s&gt;0.3)&lt;/b&gt; 영역에 분포&lt;/li&gt;
&lt;li data-end=&quot;1052&quot; data-start=&quot;1015&quot;&gt;cigarette 클래스는 더 작은 영역에 몰릴 가능성이 큼&lt;/li&gt;
&lt;li data-end=&quot;1177&quot; data-start=&quot;1053&quot;&gt;&lt;b&gt;해석:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1177&quot; data-start=&quot;1065&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1094&quot; data-start=&quot;1065&quot;&gt;작은 객체 비율이 높고, 비율이 다양한 객체 존재&lt;/li&gt;
&lt;li data-end=&quot;1127&quot; data-start=&quot;1097&quot;&gt;이는 &lt;b&gt;소형 객체 검출에 어려움을 줄 수 있음&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1177&quot; data-start=&quot;1130&quot;&gt;anchor 설정 / augmentation 전략에서 이 특성을 고려할 필요 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1182&quot; data-start=&quot;1179&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1194&quot; data-start=&quot;1184&quot; data-ke-size=&quot;size26&quot;&gt;✅ 종합 분석&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;항목평가 및 제안
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1663&quot; data-start=&quot;1196&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1663&quot; data-start=&quot;1237&quot;&gt;
&lt;tr data-end=&quot;1299&quot; data-start=&quot;1237&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1252&quot; data-start=&quot;1237&quot;&gt;&lt;b&gt;클래스 수 분포&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1299&quot; data-start=&quot;1252&quot; data-col-size=&quot;lg&quot;&gt;비교적 균형적이나, cigarette 클래스는 소형 객체로 탐지 성능 낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1341&quot; data-start=&quot;1300&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1312&quot; data-start=&quot;1300&quot;&gt;&lt;b&gt;위치 분포&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1341&quot; data-start=&quot;1312&quot; data-col-size=&quot;lg&quot;&gt;중심에 객체 몰림 &amp;rarr; 중심성 편향 가능성 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1394&quot; data-start=&quot;1342&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1354&quot; data-start=&quot;1342&quot;&gt;&lt;b&gt;크기 분포&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1394&quot; data-start=&quot;1354&quot; data-col-size=&quot;lg&quot;&gt;많은 객체가 작고 좁은 영역에 분포 &amp;rarr; 작은 객체 탐지 강화 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1452&quot; data-start=&quot;1395&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1411&quot; data-start=&quot;1395&quot;&gt;&lt;b&gt;바운딩 박스 분포&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;lg&quot; data-end=&quot;1452&quot; data-start=&quot;1411&quot;&gt;cigarette는 크기 작고 central density 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://github.com/taehuenkang/No_Smoking_Area_Project&quot;&gt;https://github.com/taehuenkang/No_Smoking_Area_Project&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/501</guid>
      <comments>https://hotari.tistory.com/501#entry501comment</comments>
      <pubDate>Tue, 13 May 2025 14:18:24 +0900</pubDate>
    </item>
    <item>
      <title>16일차</title>
      <link>https://hotari.tistory.com/500</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시멘틱 세그멘테이션(Semantic Segmentation) &lt;br /&gt;&lt;br /&gt;컴퓨터&amp;nbsp;비전&amp;nbsp;분야에서&amp;nbsp;중요한&amp;nbsp;과제&amp;nbsp;중&amp;nbsp;하나로,&amp;nbsp;이미지&amp;nbsp;내&amp;nbsp;각&amp;nbsp;픽셀을&amp;nbsp;해당하는&amp;nbsp;클래스에&amp;nbsp;매핑하는&amp;nbsp;기술임(예를&amp;nbsp;들어,&amp;nbsp;도시&amp;nbsp;풍경&amp;nbsp;사진에서&amp;nbsp;자동차,&amp;nbsp;건물,&amp;nbsp;도로&amp;nbsp;등의&amp;nbsp;각&amp;nbsp;객체를&amp;nbsp;픽셀&amp;nbsp;단위로&amp;nbsp;분류하여&amp;nbsp;특정&amp;nbsp;색상이나&amp;nbsp;라벨을&amp;nbsp;부여하는&amp;nbsp;작업이&amp;nbsp;이에&amp;nbsp;해당) &lt;br /&gt;&lt;br /&gt;시멘틱 세그멘테이션의 사용 사례 &lt;br /&gt;1. 자율 주행 자동차: 도로에서 자동차, 보행자, 신호등, 도로 경계 등을 분류하여 안전한 주행을 돕습니다.&amp;nbsp;&amp;nbsp; &lt;br /&gt;2. 의료 영상 분석: MRI나 CT 스캔에서 장기나 병변의 정확한 위치를 파악하고 진단에 활용됩니다.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;3. 위성 이미지 분석: 농지, 도시, 산림 등의 영역을 파악하여 지리적 변화를 감시합니다. &lt;br /&gt;&lt;br /&gt;주요 알고리즘 소개 &lt;br /&gt;1.&amp;nbsp;**Fully&amp;nbsp;Convolutional&amp;nbsp;Network&amp;nbsp;(FCN)**:&amp;nbsp;모든&amp;nbsp;계층을&amp;nbsp;convolutional&amp;nbsp;layer로&amp;nbsp;구성하여&amp;nbsp;이미지를&amp;nbsp;픽셀&amp;nbsp;단위로&amp;nbsp;분류하는&amp;nbsp;최초의&amp;nbsp;신경망&amp;nbsp;구조입니다.&amp;nbsp;기존의&amp;nbsp;이미지&amp;nbsp;분류용&amp;nbsp;네트워크를&amp;nbsp;기반으로&amp;nbsp;하며,&amp;nbsp;마지막&amp;nbsp;레이어에서&amp;nbsp;픽셀마다&amp;nbsp;클래스&amp;nbsp;스코어를&amp;nbsp;예측합니다. &lt;br /&gt;&lt;br /&gt;2. Encoder-Decoder 구조&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Encoder는 이미지를 받아 고차원 특징을 추출하는 부분입니다. 깊은 신경망을 통해 점진적으로 공간 정보를 압축하면서 중요한 특징을 추출합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Decoder는 압축된 특징을 사용해 고해상도로 복원하는 부분입니다. 주로 업샘플링 과정을 통해 입력 크기로 복원하며, 픽셀 단위로 분류를 수행합니다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Skip Connection: 일반적으로 Encoder-Decoder 구조에서 활용. 단순한 Encoder-Decoder 구조의 경우 공간 정보를 압축하는 과정에서 해상도가 손실되는데 이를 보완하기 위해 Encoder에서 추출된 저차원 특징을 Decoder에 직접 연결하여 결합함으로써 보다 정확한 픽셀 분류가 가능하도록 합니다. &lt;br /&gt;&lt;br /&gt;예시 알고리즘 &lt;br /&gt;- UNet: 의료 영상 분야에서 잘 알려진 알고리즘으로, 고해상도의 세그멘테이션을 위한 효과적인 구조를 갖추고 있습니다. Encoder-Decoder 구조와 함께 skip connection을 활용합니다. &lt;br /&gt;&lt;br /&gt;- DeepLab: 디렉셔널 필터링과 아트리션 컨볼루션을 활용하여 객체 경계를 세밀하게 분리합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnHwff/btsNTj4Jkw8/a137gcrMJDa8NT698KpAWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnHwff/btsNTj4Jkw8/a137gcrMJDa8NT698KpAWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnHwff/btsNTj4Jkw8/a137gcrMJDa8NT698KpAWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnHwff%2FbtsNTj4Jkw8%2Fa137gcrMJDa8NT698KpAWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;419&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R-CNN: &lt;a href=&quot;https://arxiv.org/abs/1311.2524&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1311.2524&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;객체&amp;nbsp;탐지에&amp;nbsp;사용된&amp;nbsp;초기&amp;nbsp;모델 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;주요&amp;nbsp;객체들을&amp;nbsp;바운딩&amp;nbsp;박스로&amp;nbsp;표현하여&amp;nbsp;정확히&amp;nbsp;식별하는게&amp;nbsp;목표 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Selective&amp;nbsp;Search를&amp;nbsp;통해&amp;nbsp;다양한&amp;nbsp;크기의&amp;nbsp;박스를&amp;nbsp;만들고,&amp;nbsp;region&amp;nbsp;proposal&amp;nbsp;영역&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;region&amp;nbsp;proposal&amp;nbsp;영역을&amp;nbsp;warp하여&amp;nbsp;표준화된&amp;nbsp;크기로&amp;nbsp;변환 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;AlexNet을&amp;nbsp;개량한&amp;nbsp;CNN&amp;nbsp;모델을&amp;nbsp;이용하고,&amp;nbsp;마지막&amp;nbsp;층에&amp;nbsp;SVM을&amp;nbsp;통해&amp;nbsp;객체&amp;nbsp;분류&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfwgHb/btsNRJ4JsbD/925sDW83xGVShHzJIzQ7iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfwgHb/btsNRJ4JsbD/925sDW83xGVShHzJIzQ7iK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfwgHb/btsNRJ4JsbD/925sDW83xGVShHzJIzQ7iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfwgHb%2FbtsNRJ4JsbD%2F925sDW83xGVShHzJIzQ7iK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;403&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fast R-CNN: &lt;a href=&quot;https://arxiv.org/abs/1504.08083&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1504.08083&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;R-CNN의&amp;nbsp;단점인&amp;nbsp;느린&amp;nbsp;속도를&amp;nbsp;빠른&amp;nbsp;속도로&amp;nbsp;개선 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ROI(Region&amp;nbsp;of&amp;nbsp;Interest)&amp;nbsp;풀링을&amp;nbsp;통해&amp;nbsp;한&amp;nbsp;이미지의&amp;nbsp;subregion에&amp;nbsp;대한&amp;nbsp;forward&amp;nbsp;pass&amp;nbsp;값을&amp;nbsp;공유 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;R-CNN은&amp;nbsp;CNN&amp;nbsp;모델로&amp;nbsp;image&amp;nbsp;feature를&amp;nbsp;추출,&amp;nbsp;SVM&amp;nbsp;모델로&amp;nbsp;분류,&amp;nbsp;Regressor&amp;nbsp;모델로&amp;nbsp;bounding&amp;nbsp;box를&amp;nbsp;맞추는&amp;nbsp;작업으로&amp;nbsp;분류되어&amp;nbsp;있지만,&amp;nbsp;Fast&amp;nbsp;R-CNN은&amp;nbsp;하나의&amp;nbsp;모델로&amp;nbsp;동작 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Top&amp;nbsp;layer에&amp;nbsp;softmax&amp;nbsp;layer를&amp;nbsp;둬서&amp;nbsp;CNN&amp;nbsp;결과를&amp;nbsp;class로&amp;nbsp;출력 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Box&amp;nbsp;regression&amp;nbsp;layer를&amp;nbsp;softmax&amp;nbsp;layer에&amp;nbsp;평행하게&amp;nbsp;두어&amp;nbsp;bounding&amp;nbsp;box&amp;nbsp;좌표를&amp;nbsp;출력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;514&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CFVz2/btsNSfhMWE7/tnJpd9cnyZK0NNIUgdrj8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CFVz2/btsNSfhMWE7/tnJpd9cnyZK0NNIUgdrj8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CFVz2/btsNSfhMWE7/tnJpd9cnyZK0NNIUgdrj8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCFVz2%2FbtsNSfhMWE7%2FtnJpd9cnyZK0NNIUgdrj8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;514&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;514&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Faster R-CNN: &lt;a href=&quot;https://arxiv.org/abs/1506.01497&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1506.01497&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Fast&amp;nbsp;R-CNN은&amp;nbsp;가능성&amp;nbsp;있는&amp;nbsp;다양한&amp;nbsp;bounding&amp;nbsp;box들,&amp;nbsp;즉&amp;nbsp;ROI를&amp;nbsp;생성하는&amp;nbsp;과정인&amp;nbsp;selective&amp;nbsp;search가&amp;nbsp;느려&amp;nbsp;region&amp;nbsp;proposer에서&amp;nbsp;병목이&amp;nbsp;발생 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지&amp;nbsp;분류(classification)의&amp;nbsp;첫&amp;nbsp;단계인&amp;nbsp;CNN의&amp;nbsp;forward&amp;nbsp;pass를&amp;nbsp;통해&amp;nbsp;얻어진&amp;nbsp;feature들을&amp;nbsp;기반으로&amp;nbsp;영역을&amp;nbsp;제안 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;CNN&amp;nbsp;결과를&amp;nbsp;selective&amp;nbsp;search&amp;nbsp;알고리즘&amp;nbsp;대신&amp;nbsp;region&amp;nbsp;proposal에&amp;nbsp;이용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm7T8m/btsNUdW9jP2/vfA44PpxgUTpV4yKGjgsVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm7T8m/btsNUdW9jP2/vfA44PpxgUTpV4yKGjgsVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm7T8m/btsNUdW9jP2/vfA44PpxgUTpV4yKGjgsVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm7T8m%2FbtsNUdW9jP2%2FvfA44PpxgUTpV4yKGjgsVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;635&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;635&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;k개의&amp;nbsp;일반적인&amp;nbsp;비율을&amp;nbsp;지닌&amp;nbsp;anchor&amp;nbsp;box를&amp;nbsp;이용하여&amp;nbsp;하나의&amp;nbsp;bounding&amp;nbsp;box&amp;nbsp;및&amp;nbsp;score를&amp;nbsp;이미지의&amp;nbsp;위치별로&amp;nbsp;출력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kRGN1/btsNUccRQH5/urUSNI8AzuKYDGK8yNsC2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kRGN1/btsNUccRQH5/urUSNI8AzuKYDGK8yNsC2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kRGN1/btsNUccRQH5/urUSNI8AzuKYDGK8yNsC2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkRGN1%2FbtsNUccRQH5%2FurUSNI8AzuKYDGK8yNsC2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;704&quot; height=&quot;416&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mask R-CNN: &lt;a href=&quot;https://arxiv.org/abs/1703.06870&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1703.06870&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;- Pixel 레벨의 세그멘테이션&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RolPool에서&amp;nbsp;선택된&amp;nbsp;feature&amp;nbsp;map이&amp;nbsp;원래&amp;nbsp;이미지&amp;nbsp;영역으로&amp;nbsp;약간&amp;nbsp;잘못된&amp;nbsp;정렬이&amp;nbsp;발생한&amp;nbsp;부분을&amp;nbsp;RolAlign을&amp;nbsp;통해&amp;nbsp;조정하여&amp;nbsp;정확하게&amp;nbsp;정렬 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Mask&amp;nbsp;R-CNN은&amp;nbsp;Mask가&amp;nbsp;생성되면,&amp;nbsp;Faster&amp;nbsp;R-CNN으로&amp;nbsp;생성된&amp;nbsp;classification과&amp;nbsp;bounding&amp;nbsp;box들을&amp;nbsp;합쳐&amp;nbsp;정확한&amp;nbsp;세그멘테이션&amp;nbsp;가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;U-Net 기반 세그멘테이션&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;사용된&amp;nbsp;모델은&amp;nbsp;수정된&amp;nbsp;U-Net(&lt;a href=&quot;https://arxiv.org/abs/1505.04597)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1505.04597)&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;U-Net이라&amp;nbsp;불리는&amp;nbsp;인코더(다운샘플링-&amp;nbsp;Contracting&amp;nbsp;Path:피처맵의&amp;nbsp;크기가&amp;nbsp;줄어듬,&amp;nbsp;572-&amp;gt;&amp;nbsp;284-&amp;gt;140-&amp;gt;68-&amp;gt;332-&amp;gt;30)와&amp;nbsp;디코더(업샘플링-expanding&amp;nbsp;path:피처맵의&amp;nbsp;크기가&amp;nbsp;커)를&amp;nbsp;포함한&amp;nbsp;구조는&amp;nbsp;정교한&amp;nbsp;픽셀&amp;nbsp;단위의&amp;nbsp;segmentation이&amp;nbsp;요구되는&amp;nbsp;biomedical&amp;nbsp;image&amp;nbsp;segmentation&amp;nbsp;task의&amp;nbsp;핵심&amp;nbsp;요소 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;다운샘플링과정에서&amp;nbsp;피처맵&amp;nbsp;사이즈는&amp;nbsp;줄어드나&amp;nbsp;채널의&amp;nbsp;수는&amp;nbsp;증가하기&amp;nbsp;때문에&amp;nbsp;압축되는&amp;nbsp;과정에서&amp;nbsp;정보가&amp;nbsp;손실된다기보다&amp;nbsp;다른&amp;nbsp;형태로&amp;nbsp;추출한다고&amp;nbsp;생각할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;최종&amp;nbsp;output&amp;nbsp;이&amp;nbsp;2&amp;nbsp;는&amp;nbsp;388*388&amp;nbsp;피처에서&amp;nbsp;binary&amp;nbsp;classifcation&amp;nbsp;진행 &lt;br /&gt;-&amp;nbsp;Encoder-decoder&amp;nbsp;구조&amp;nbsp;또한&amp;nbsp;semantic&amp;nbsp;segmentation을&amp;nbsp;위한&amp;nbsp;CNN&amp;nbsp;구조로&amp;nbsp;자주&amp;nbsp;활용 &lt;br /&gt;-&amp;nbsp;Encoder&amp;nbsp;부분에서는&amp;nbsp;점진적으로&amp;nbsp;spatial&amp;nbsp;dimension을&amp;nbsp;줄여가면서&amp;nbsp;고차원의&amp;nbsp;semantic&amp;nbsp;정보를&amp;nbsp;convolution&amp;nbsp;filter가&amp;nbsp;추출해낼&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;함 &lt;br /&gt;-&amp;nbsp;Decoder&amp;nbsp;부분에서는&amp;nbsp;encoder에서&amp;nbsp;spatial&amp;nbsp;dimension&amp;nbsp;축소로&amp;nbsp;인해&amp;nbsp;손실된&amp;nbsp;spatial&amp;nbsp;정보를&amp;nbsp;점진적으로&amp;nbsp;복원하여&amp;nbsp;보다&amp;nbsp;정교한&amp;nbsp;boundary&amp;nbsp;segmentation을&amp;nbsp;완성 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;Skip&amp;nbsp;connection&amp;nbsp;:&amp;nbsp;input&amp;nbsp;-&amp;gt;&amp;nbsp;output&amp;nbsp;채널&amp;nbsp;방향으로&amp;nbsp;concatenate&amp;nbsp;함&amp;nbsp;(다운샘플링과&amp;nbsp;업샘플링을&amp;nbsp;거친값과&amp;nbsp;입력&amp;nbsp;X&amp;nbsp;값을&amp;nbsp;그대로&amp;nbsp;가져와&amp;nbsp;둘&amp;nbsp;다&amp;nbsp;활용) &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;U-Net은&amp;nbsp;기본적인&amp;nbsp;encoder-decoder&amp;nbsp;구조와&amp;nbsp;달리&amp;nbsp;Spatial&amp;nbsp;정보를&amp;nbsp;복원하는&amp;nbsp;과정에서&amp;nbsp;이전&amp;nbsp;encoder&amp;nbsp;feature&amp;nbsp;map&amp;nbsp;중&amp;nbsp;동일한&amp;nbsp;크기를&amp;nbsp;지닌&amp;nbsp;feature&amp;nbsp;map을&amp;nbsp;가져&amp;nbsp;와&amp;nbsp;prior로&amp;nbsp;활용함으로써&amp;nbsp;더&amp;nbsp;정확한&amp;nbsp;boundary&amp;nbsp;segmentation이&amp;nbsp;가능하게&amp;nbsp;함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;795&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3ShtR/btsNUbE14FV/GMKLkwsSC50yuo9GJUJYf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3ShtR/btsNUbE14FV/GMKLkwsSC50yuo9GJUJYf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3ShtR/btsNUbE14FV/GMKLkwsSC50yuo9GJUJYf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3ShtR%2FbtsNUbE14FV%2FGMKLkwsSC50yuo9GJUJYf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1196&quot; height=&quot;795&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oxford-IIIT Pets 데이터셋 &lt;br /&gt;&lt;br /&gt;- Parkhi et al이 만든 [Oxford-IIIT Pet Dataset](&lt;a href=&quot;https://www.robots.ox.ac.uk/~vgg/data/pets/)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.robots.ox.ac.uk/~vgg/data/pets/)&lt;/a&gt;&amp;nbsp;데이터&amp;nbsp;세트는&amp;nbsp;영상,&amp;nbsp;해당&amp;nbsp;레이블과&amp;nbsp;픽셀&amp;nbsp;단위의&amp;nbsp;마스크로&amp;nbsp;구성 &lt;br /&gt;-&amp;nbsp;마스크는&amp;nbsp;기본적으로&amp;nbsp;각&amp;nbsp;픽셀의&amp;nbsp;레이블 &lt;br /&gt;-&amp;nbsp;각&amp;nbsp;픽셀은&amp;nbsp;다음&amp;nbsp;세&amp;nbsp;가지&amp;nbsp;범주&amp;nbsp;중&amp;nbsp;하나 &lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;class&amp;nbsp;1&amp;nbsp;:&amp;nbsp;애완동물이&amp;nbsp;속한&amp;nbsp;픽셀 &lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;class&amp;nbsp;2&amp;nbsp;:&amp;nbsp;애완동물과&amp;nbsp;인접한&amp;nbsp;픽셀 &lt;br /&gt;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;class&amp;nbsp;3&amp;nbsp;:&amp;nbsp;위에&amp;nbsp;속하지&amp;nbsp;않는&amp;nbsp;경우/주변&amp;nbsp;픽셀 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;Images:&amp;nbsp;&lt;a href=&quot;https://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;Annotations:&amp;nbsp;&lt;a href=&quot;https://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepLab 기반 세그멘테이션 &lt;br /&gt;&lt;br /&gt;DeepLab V1: [Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs](&lt;a href=&quot;https://arxiv.org/abs/1412.7062),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1412.7062),&lt;/a&gt;&amp;nbsp;ICLR&amp;nbsp;2015. &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Atrous&amp;nbsp;convolution은&amp;nbsp;기존&amp;nbsp;convolution과&amp;nbsp;다르게&amp;nbsp;필터&amp;nbsp;내부에&amp;nbsp;빈&amp;nbsp;공간을&amp;nbsp;둔&amp;nbsp;채로&amp;nbsp;작동 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;기존&amp;nbsp;convolution과&amp;nbsp;동일한&amp;nbsp;양의&amp;nbsp;파라미터와&amp;nbsp;계산량을&amp;nbsp;유지하면서&amp;nbsp;field&amp;nbsp;of&amp;nbsp;view&amp;nbsp;(한&amp;nbsp;픽셀이&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;영역)를&amp;nbsp;크게&amp;nbsp;가져갈&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Semantic&amp;nbsp;segmentation에서&amp;nbsp;일반적으로&amp;nbsp;높은&amp;nbsp;성능을&amp;nbsp;내기&amp;nbsp;위해서는&amp;nbsp;convolutional&amp;nbsp;neural&amp;nbsp;network의&amp;nbsp;마지막에&amp;nbsp;존재하는&amp;nbsp;한&amp;nbsp;픽셀이&amp;nbsp;입력값에서&amp;nbsp;어느&amp;nbsp;크기의&amp;nbsp;영역을&amp;nbsp;커버할&amp;nbsp;수&amp;nbsp;있는지를&amp;nbsp;결정하는&amp;nbsp;receptive&amp;nbsp;field&amp;nbsp;크기가&amp;nbsp;중요 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Atrous&amp;nbsp;convolution을&amp;nbsp;활용하면&amp;nbsp;파라미터&amp;nbsp;수를&amp;nbsp;늘리지&amp;nbsp;않으면서도&amp;nbsp;receptive&amp;nbsp;field를&amp;nbsp;크게&amp;nbsp;키울&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;DeepLab&amp;nbsp;계열에서는&amp;nbsp;이를&amp;nbsp;적극적으로&amp;nbsp;활용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2HzB3/btsNSfPEAUW/66GmRtQjuBGonab4lFG03k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2HzB3/btsNSfPEAUW/66GmRtQjuBGonab4lFG03k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2HzB3/btsNSfPEAUW/66GmRtQjuBGonab4lFG03k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2HzB3%2FbtsNSfPEAUW%2F66GmRtQjuBGonab4lFG03k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;638&quot; height=&quot;303&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepLab V2: [DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs](&lt;a href=&quot;https://arxiv.org/abs/1606.00915),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1606.00915),&lt;/a&gt;&amp;nbsp;TPAMI&amp;nbsp;2017. &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Semantic&amp;nbsp;segmentaion의&amp;nbsp;성능을&amp;nbsp;높이기&amp;nbsp;위한&amp;nbsp;방법&amp;nbsp;중&amp;nbsp;하나로,&amp;nbsp;spatial&amp;nbsp;pyramid&amp;nbsp;pooling&amp;nbsp;기법을&amp;nbsp;자주&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Feature&amp;nbsp;map으로부터&amp;nbsp;여러&amp;nbsp;개의&amp;nbsp;rate가&amp;nbsp;다른&amp;nbsp;atrous&amp;nbsp;convolution을&amp;nbsp;병렬로&amp;nbsp;적용한&amp;nbsp;뒤,&amp;nbsp;이를&amp;nbsp;다시&amp;nbsp;합쳐주는&amp;nbsp;atrous&amp;nbsp;spatial&amp;nbsp;pyramid&amp;nbsp;pooling&amp;nbsp;(ASPP)&amp;nbsp;기법을&amp;nbsp;활용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;multi-scale&amp;nbsp;context를&amp;nbsp;모델&amp;nbsp;구조로&amp;nbsp;구현하여&amp;nbsp;보다&amp;nbsp;정확한&amp;nbsp;semantic&amp;nbsp;segmentation을&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciuHPj/btsNSfB8qgN/NroZ2YA5kqChOKvzkpt0Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciuHPj/btsNSfB8qgN/NroZ2YA5kqChOKvzkpt0Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciuHPj/btsNSfB8qgN/NroZ2YA5kqChOKvzkpt0Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciuHPj%2FbtsNSfB8qgN%2FNroZ2YA5kqChOKvzkpt0Nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;241&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepLab V3: [Rethinking Atrous Convolution for Semantic Image Segmentation](&lt;a href=&quot;https://arxiv.org/abs/1706.05587),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1706.05587),&lt;/a&gt;&amp;nbsp;arXiv&amp;nbsp;2017. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Encoder:&amp;nbsp;ResNet&amp;nbsp;with&amp;nbsp;Atrous&amp;nbsp;convolution &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Atrous&amp;nbsp;Spatial&amp;nbsp;Pyramid&amp;nbsp;Pooling&amp;nbsp;(ASPP) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Decoder:&amp;nbsp;Bilinear&amp;nbsp;Upsampling&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eg5yTM/btsNR1Et23g/KVJ0IjSKkkCrJD1VxkAZf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eg5yTM/btsNR1Et23g/KVJ0IjSKkkCrJD1VxkAZf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eg5yTM/btsNR1Et23g/KVJ0IjSKkkCrJD1VxkAZf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feg5yTM%2FbtsNR1Et23g%2FKVJ0IjSKkkCrJD1VxkAZf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;375&quot; height=&quot;391&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepLab V3+: [Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation](&lt;a href=&quot;https://arxiv.org/pdf/1802.02611.pdf),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/1802.02611.pdf),&lt;/a&gt;&amp;nbsp;arXiv&amp;nbsp;2018. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Encoder:&amp;nbsp;ResNet&amp;nbsp;with&amp;nbsp;Atrous&amp;nbsp;Convolution&amp;nbsp;&amp;rarr;&amp;nbsp;Xception&amp;nbsp;(Inception&amp;nbsp;with&amp;nbsp;Separable&amp;nbsp;Convolution) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ASPP&amp;nbsp;&amp;rarr;&amp;nbsp;ASSPP&amp;nbsp;(Atrous&amp;nbsp;Separable&amp;nbsp;Spatial&amp;nbsp;Pyramid&amp;nbsp;Pooling) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Decoder:&amp;nbsp;Bilinear&amp;nbsp;Upsampling&amp;nbsp;&amp;rarr;&amp;nbsp;Simplified&amp;nbsp;U-Net&amp;nbsp;style&amp;nbsp;decoder&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OGZuf/btsNTm8fGgk/bbk1hYjNKRFkbSd5ljHIBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OGZuf/btsNTm8fGgk/bbk1hYjNKRFkbSd5ljHIBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OGZuf/btsNTm8fGgk/bbk1hYjNKRFkbSd5ljHIBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOGZuf%2FbtsNTm8fGgk%2Fbbk1hYjNKRFkbSd5ljHIBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;394&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;331&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcCrbr/btsNSfPEDLc/INjbTRQPHWl7kgvEKK3R60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcCrbr/btsNSfPEDLc/INjbTRQPHWl7kgvEKK3R60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcCrbr/btsNSfPEDLc/INjbTRQPHWl7kgvEKK3R60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcCrbr%2FbtsNSfPEDLc%2FINjbTRQPHWl7kgvEKK3R60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;331&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;331&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 구성 &lt;br /&gt;&lt;br /&gt;인코더-디코더 구조를 확장 &lt;br /&gt;인코더 모듈: 확장된 컨볼루션을 여러 척도로 적용하여 다중 스케일 상황 정보 처리 &lt;br /&gt;디코더 모듈: 객체 경계를 따라 분할 결과 조정 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;확장된 컨볼루션(Dilated convolution) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;컨볼루션&amp;nbsp;확장을&amp;nbsp;통해&amp;nbsp;네트워크&amp;nbsp;깊숙히&amp;nbsp;들어가며&amp;nbsp;스트라이드를&amp;nbsp;일정하게&amp;nbsp;유지&amp;nbsp;가능 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;매개변수의&amp;nbsp;수나&amp;nbsp;계산량을&amp;nbsp;늘리지&amp;nbsp;않고도&amp;nbsp;더&amp;nbsp;큰&amp;nbsp;시야를&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;더&amp;nbsp;큰&amp;nbsp;특징&amp;nbsp;맵&amp;nbsp;출력이&amp;nbsp;가능하여&amp;nbsp;세그멘테이션에&amp;nbsp;유용함 &lt;br /&gt;&lt;br /&gt;확장된 공간 피라미드 풀링(Dilated Spatial Pyramid Pooling) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;샘플링&amp;nbsp;속도가&amp;nbsp;커질수록&amp;nbsp;유효한&amp;nbsp;필터&amp;nbsp;가중치(유효한&amp;nbsp;특징&amp;nbsp;영역에&amp;nbsp;적용되는&amp;nbsp;가중치)의&amp;nbsp;수가&amp;nbsp;작아짐&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1195&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blXtXi/btsNSf9WZeG/nOTsHWH1q4B5DPhCsN70KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blXtXi/btsNSf9WZeG/nOTsHWH1q4B5DPhCsN70KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blXtXi/btsNSf9WZeG/nOTsHWH1q4B5DPhCsN70KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblXtXi%2FbtsNSf9WZeG%2FnOTsHWH1q4B5DPhCsN70KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1195&quot; height=&quot;628&quot; data-origin-width=&quot;1195&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전 훈련된 ResNet50을 백본 모델로 사용 &lt;br /&gt;`conv4_block6_2_relu` 블록에서 저수준의 특징 사용 &lt;br /&gt;&lt;br /&gt;인코더 특징은 인자 4에 의해 쌍선형 업샘플링 &lt;br /&gt;동일한 공간 해상도를 가진 네트워크 백본에서 저수준 특징과 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Detectron Mask R-CNN &lt;br /&gt;&lt;br /&gt;페이스북 인공지능 연구소(FAIR)에서 공개한 플랫폼 &lt;br /&gt;빠르고 유연한 사물 탐지 가능&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;343&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JGU62/btsNSvratLU/7BY3O0jOQNfHYR09G8fIs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JGU62/btsNSvratLU/7BY3O0jOQNfHYR09G8fIs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JGU62/btsNSvratLU/7BY3O0jOQNfHYR09G8fIs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJGU62%2FbtsNSvratLU%2F7BY3O0jOQNfHYR09G8fIs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;343&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;343&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Detectron2&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cySL5M/btsNTxu0hXY/7KAowQPYOFMUyIMDzawXB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cySL5M/btsNTxu0hXY/7KAowQPYOFMUyIMDzawXB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cySL5M/btsNTxu0hXY/7KAowQPYOFMUyIMDzawXB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcySL5M%2FbtsNTxu0hXY%2F7KAowQPYOFMUyIMDzawXB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;93&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이스북 인공지능 연구소(FAIR)에서 개발한 객체 세그멘테이션 프레임워크 &lt;br /&gt;페이스북에서 개발한 DensePose, Mask R-CNN 등을 Detectron2에서 제공 &lt;br /&gt;손쉽게 다양한 사물들을 탐지하고 세그먼테이션하여, 객체의 유형, 크기, 위치 등을 자동으로 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bVczuu/btsNSaOOvaZ/CJfh9Qlldaiux54wLYPekK/03-11_InstanceSegmentation_YOLOv8_Basic.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03-11_InstanceSegmentation_YOLOv8_Basic.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;6.23MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/beSDJu/btsNTjKtT0Q/GcoXDMpgx0YhigDE2cpUC0/03-12_InstanceSegmentation_YOLOv8_CustomData_TACO_Roboflow_Windows.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03-12_InstanceSegmentation_YOLOv8_CustomData_TACO_Roboflow_Windows.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;3.03MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dL5UWx/btsNRPKF3cR/qHcKFtIaRDbA2XKAtLLKik/04-11_PoseEstimation_YOLOv8_Basic.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04-11_PoseEstimation_YOLOv8_Basic.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.39MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b6gEAp/btsNTQumbDv/Xm1M3jgCXjZFi61NiNsEc0/04-13_FacePoseHandsDetection_Mediapipe.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04-13_FacePoseHandsDetection_Mediapipe.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/AlaNV/btsNTSl4TBX/MNkD1KH1CrGQB827obGW7K/01-1_imgClassifcation.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01-1_imgClassifcation.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.03MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cqNewv/btsNUz7mOm9/ZiN3eMxepxxZ6svD6iSkHk/01-2_videoClassification.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01-2_videoClassification.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;4.46MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/qsJ2P/btsNUG6gbo9/E319g89o8ZqX1LFmVejcr0/02_objDetection.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02_objDetection.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.46MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/lEKIZ/btsNUxhsuz9/qMiv45ttxTzl48rKdAsWY0/03_imgCaptioning.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03_imgCaptioning.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/xaHe6/btsNUrICrUy/GKktnXcXCKyKVlzivkgBhK/04_imgTextGeneration.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04_imgTextGeneration.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;ObjectDetection : Custom Datasets 만들기&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;lt; Object Detection을 위한 Custom Datasets 만들기 &amp;gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Data Labelling 도구&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/heartexlabs/labelImg&quot;&gt;labelImg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://roboflow.com/?utm_source=augmented-startups&amp;amp;utm_medium=video&amp;amp;utm_campaign=generic&quot;&gt;Roboflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://app.cvat.ai/&quot;&gt;CVAT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. CVAT 을 사용하여 Annotation 하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) &lt;span style=&quot;background-color: #fbecdd;&quot; data-token-index=&quot;1&quot;&gt;Project 생성&lt;/span&gt;하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dE16CC/btsNUtNp0EB/lfL0SkKAANy5zozbgvk7u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dE16CC/btsNUtNp0EB/lfL0SkKAANy5zozbgvk7u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dE16CC/btsNUtNp0EB/lfL0SkKAANy5zozbgvk7u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdE16CC%2FbtsNUtNp0EB%2FlfL0SkKAANy5zozbgvk7u1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;265&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Project Name 지정 후 [ Constructor] 탭에서 label 생성하기&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;② ~ ⑤ 번까지 반복하여 20개의 label 생성하기 : 색상은 각기 다르게 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGymVF/btsNUvqWeCW/DCes3pK7Wcm5tTWhkn4eM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGymVF/btsNUvqWeCW/DCes3pK7Wcm5tTWhkn4eM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGymVF/btsNUvqWeCW/DCes3pK7Wcm5tTWhkn4eM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGymVF%2FbtsNUvqWeCW%2FDCes3pK7Wcm5tTWhkn4eM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;664&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;20개 label :&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coZtM7/btsNTQaY5SF/CGqvik0f9KQEXdRsPYxMm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coZtM7/btsNTQaY5SF/CGqvik0f9KQEXdRsPYxMm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coZtM7/btsNTQaY5SF/CGqvik0f9KQEXdRsPYxMm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoZtM7%2FbtsNTQaY5SF%2FCGqvik0f9KQEXdRsPYxMm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;467&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;20개의 label 생성 후 &amp;ldquo;Submit &amp;amp; Open&amp;rdquo; 버튼 클릭하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3Q4k2/btsNS57NuUj/PgdSzma7p5UdWNnIJfk4tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3Q4k2/btsNS57NuUj/PgdSzma7p5UdWNnIJfk4tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3Q4k2/btsNS57NuUj/PgdSzma7p5UdWNnIJfk4tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3Q4k2%2FbtsNS57NuUj%2FPgdSzma7p5UdWNnIJfk4tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;318&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) &lt;span style=&quot;background-color: #fbecdd;&quot; data-token-index=&quot;1&quot;&gt;Task 생성&lt;/span&gt;하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdP2dG/btsNU7JzJLa/9SkO9Fzz1d7dk5amw2Ypi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdP2dG/btsNU7JzJLa/9SkO9Fzz1d7dk5amw2Ypi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdP2dG/btsNU7JzJLa/9SkO9Fzz1d7dk5amw2Ypi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdP2dG%2FbtsNU7JzJLa%2F9SkO9Fzz1d7dk5amw2Ypi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;160&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1raaD/btsNSvFFSj7/yt5Qjoa9okokKTleQhdrm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1raaD/btsNSvFFSj7/yt5Qjoa9okokKTleQhdrm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1raaD/btsNSvFFSj7/yt5Qjoa9okokKTleQhdrm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1raaD%2FbtsNSvFFSj7%2Fyt5Qjoa9okokKTleQhdrm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;496&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;압축파일 해제하여 file upload하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://prod-files-secure.s3.us-west-2.amazonaws.com/46c48f51-38e5-4155-b865-17095aa29454/8b2a95c8-7d6f-45fb-8107-ab626fca2ae1/custom_yolo_images.zip&quot;&gt;custom_yolo_images.zip&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;ldquo;Submit &amp;amp; Open&amp;rdquo; 클릭하기
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Task 목록에서 생성된 Task를 open 한 후 Jobs 실행하기&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Job 번호 클릭하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0zyOw/btsNURmDg5e/kK3o38HB5ktwN3y0SGJGWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0zyOw/btsNURmDg5e/kK3o38HB5ktwN3y0SGJGWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0zyOw/btsNURmDg5e/kK3o38HB5ktwN3y0SGJGWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0zyOw%2FbtsNURmDg5e%2FkK3o38HB5ktwN3y0SGJGWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;302&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;labelling 진행하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bItrqa/btsNUCwyOfG/0e8120l94akafnovlfxIA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bItrqa/btsNUCwyOfG/0e8120l94akafnovlfxIA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bItrqa/btsNUCwyOfG/0e8120l94akafnovlfxIA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbItrqa%2FbtsNUCwyOfG%2F0e8120l94akafnovlfxIA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;439&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5장의 이미지의 labelling 완료되면 상단 &amp;lsquo;Save&amp;rdquo; 버튼 후 &amp;ldquo;Export job dataset&amp;rdquo; 클릭하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C5e8g/btsNTkKrzQa/MLQaRmYvwXOKg971KaGQHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C5e8g/btsNTkKrzQa/MLQaRmYvwXOKg971KaGQHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C5e8g/btsNTkKrzQa/MLQaRmYvwXOKg971KaGQHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC5e8g%2FbtsNTkKrzQa%2FMLQaRmYvwXOKg971KaGQHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;195&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내보내기 형식 지정하고 이름 지정후 &amp;ldquo;OK&amp;rdquo; 클릭하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9yXjo/btsNUt0XJfh/Jx2DLHSgrlHcBao6jQUxmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9yXjo/btsNUt0XJfh/Jx2DLHSgrlHcBao6jQUxmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9yXjo/btsNUt0XJfh/Jx2DLHSgrlHcBao6jQUxmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9yXjo%2FbtsNUt0XJfh%2FJx2DLHSgrlHcBao6jQUxmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;362&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Roboflow&lt;span data-token-index=&quot;1&quot;&gt; 을 사용하여 Annotation 하기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 프로젝트 생성하기 : New Project&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 데이터파일 업로드하기 : Upload Data&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 클래스 등록하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4) 어노테이팅하기 : Start Annotation&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) 버전 생성하기 : 3~5번 단계까지 진행하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6) 데이터셋 다운로드하기&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/500</guid>
      <comments>https://hotari.tistory.com/500#entry500comment</comments>
      <pubDate>Mon, 12 May 2025 16:53:25 +0900</pubDate>
    </item>
    <item>
      <title>15일차</title>
      <link>https://hotari.tistory.com/499</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.09&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Pytorch 및 필요한 라이브러리 설치하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Anaconda3 내 설정만으로 PyTorch GPU 환경을 설정하는 방법&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;conda 업데이트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda update -n base -c defaults conda&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가상환경 생성 (torch-gpu로 생성, 필요하면 이름 변경)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda create -n torch-gpu python=3.10&lt;/li&gt;
&lt;li&gt;conda activate torch-gpu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CUDA 11.8 / CuDNN 8.9.7 설치
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda install -c conda-forge cudatoolkit=11.8 cudnn=8.9.7 ( or &lt;b&gt;conda-forge&lt;/b&gt;와 &lt;b&gt;defaults&lt;/b&gt; 채널에서는 cudatoolkit=12.8이 제공되지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PyTorch 2.3.0 설치
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda install pytorch==2.3.0 torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;커널 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pip install ipykernel&lt;/li&gt;
&lt;li&gt;python -m ipykernel install --user --name=torch-gpu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;설치 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Object Detection&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://teachablemachine.withgoogle.com/&quot;&gt;Teachable Machine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;949&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UDfw1/btsNRLTSIlZ/4Bwk9wUKnjkTH2WHYEp2Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UDfw1/btsNRLTSIlZ/4Bwk9wUKnjkTH2WHYEp2Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UDfw1/btsNRLTSIlZ/4Bwk9wUKnjkTH2WHYEp2Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUDfw1%2FbtsNRLTSIlZ%2F4Bwk9wUKnjkTH2WHYEp2Nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1329&quot; height=&quot;949&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;949&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 객체 탐지 (Object Detection)&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;객체&amp;nbsp;탐지는&amp;nbsp;컴퓨터&amp;nbsp;비전과&amp;nbsp;이미지&amp;nbsp;처리와&amp;nbsp;관련된&amp;nbsp;컴퓨터&amp;nbsp;기술로써&amp;nbsp;디지털&amp;nbsp;이미지와&amp;nbsp;비디오를&amp;nbsp;특정한&amp;nbsp;계열의&amp;nbsp;시멘틱&amp;nbsp;객체&amp;nbsp;인스턴스를&amp;nbsp;감지하는&amp;nbsp;일을&amp;nbsp;다룬다 &lt;br /&gt;-&amp;nbsp;각&amp;nbsp;객체&amp;nbsp;범주의&amp;nbsp;모든&amp;nbsp;인스턴스의&amp;nbsp;위치와&amp;nbsp;배율을&amp;nbsp;나타내는&amp;nbsp;축&amp;nbsp;정렬&amp;nbsp;경계&amp;nbsp;상자와&amp;nbsp;함께&amp;nbsp;이미지에&amp;nbsp;있는&amp;nbsp;객체&amp;nbsp;범주&amp;nbsp;목록&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;한&amp;nbsp;이미지에서&amp;nbsp;여러&amp;nbsp;객체와&amp;nbsp;그&amp;nbsp;경계&amp;nbsp;상자(bounding&amp;nbsp;box)를&amp;nbsp;탐지(여러&amp;nbsp;객체를&amp;nbsp;분류하고&amp;nbsp;위치를&amp;nbsp;추정하는&amp;nbsp;방법) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;객체&amp;nbsp;탐지&amp;nbsp;알고리즘은&amp;nbsp;일반적으로&amp;nbsp;이미지를&amp;nbsp;입력으로&amp;nbsp;받고,&amp;nbsp;경계&amp;nbsp;상자와&amp;nbsp;객체&amp;nbsp;클래스&amp;nbsp;리스트를&amp;nbsp;출력 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;경계&amp;nbsp;상자에&amp;nbsp;대해&amp;nbsp;그에&amp;nbsp;대응하는&amp;nbsp;예측&amp;nbsp;클래스와&amp;nbsp;클래스의&amp;nbsp;신뢰도(confidence)를&amp;nbsp;출력 &lt;br /&gt;&lt;br /&gt;Applications &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;자율&amp;nbsp;주행&amp;nbsp;자동차에서&amp;nbsp;다른&amp;nbsp;자동차와&amp;nbsp;보행자를&amp;nbsp;찾을&amp;nbsp;때 &lt;br /&gt;-&amp;nbsp;의료&amp;nbsp;분야에서&amp;nbsp;방사선&amp;nbsp;사진을&amp;nbsp;사용해&amp;nbsp;종양이나&amp;nbsp;위험한&amp;nbsp;조직을&amp;nbsp;찾을&amp;nbsp;때 &lt;br /&gt;-&amp;nbsp;제조업에서&amp;nbsp;조립&amp;nbsp;로봇이&amp;nbsp;제품을&amp;nbsp;조립하거나&amp;nbsp;수리할&amp;nbsp;때 &lt;br /&gt;-&amp;nbsp;보안&amp;nbsp;산업에서&amp;nbsp;위협을&amp;nbsp;탐지하거나&amp;nbsp;사람&amp;nbsp;수를&amp;nbsp;셀&amp;nbsp;때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Bounding Box&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지에서 하나의 객체 전체를 포함하는 가장 작은 직사각형&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/esIexN/btsNQ2V7rga/vSjBcpSpRCNKjK4Ys2swfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/esIexN/btsNQ2V7rga/vSjBcpSpRCNKjK4Ys2swfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/esIexN/btsNQ2V7rga/vSjBcpSpRCNKjK4Ys2swfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FesIexN%2FbtsNQ2V7rga%2FvSjBcpSpRCNKjK4Ys2swfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;843&quot; height=&quot;510&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) IOU (Intersection Over Union)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 실측값(Ground Truth)과 모델이 예측한 값이 얼마나 겹치는지를 나타내는 지표, 0~1 사이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예측 Bounding Box와 실제 Ground Truth가 겹치는 부분/예측 Bounding Box와 Ground Truth 겹치는 부분, 즉 두 집합의 교집합/합집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Object 영역을 얼마나 정확하게 찾는지 판단. IOU가 0.5 이상이면 2/3 정도 겹치는 정도로 이 정도면 예측을 성공했다고 할 수 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yf0og/btsNPzgMeEo/mo0BoqVkLjRkHgKKn9TaKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yf0og/btsNPzgMeEo/mo0BoqVkLjRkHgKKn9TaKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yf0og/btsNPzgMeEo/mo0BoqVkLjRkHgKKn9TaKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyf0og%2FbtsNPzgMeEo%2Fmo0BoqVkLjRkHgKKn9TaKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;232&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IOU가 높을수록 잘 예측한 모델&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxzMP3/btsNOhALSk0/VQ8MNBawKyQ2KhF7DfNVF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxzMP3/btsNOhALSk0/VQ8MNBawKyQ2KhF7DfNVF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxzMP3/btsNOhALSk0/VQ8MNBawKyQ2KhF7DfNVF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxzMP3%2FbtsNOhALSk0%2FVQ8MNBawKyQ2KhF7DfNVF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;162&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예시&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHUE8U/btsNPxiZBVi/rtvwDCqJJqxwx1eofYBiS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHUE8U/btsNPxiZBVi/rtvwDCqJJqxwx1eofYBiS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHUE8U/btsNPxiZBVi/rtvwDCqJJqxwx1eofYBiS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHUE8U%2FbtsNPxiZBVi%2FrtvwDCqJJqxwx1eofYBiS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;442&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) NMS (Non-Maximum Suppression, 비최댓값 억제)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다수의 중복된 예측을 제거하여 최종적으로 하나의 예측만 남기는 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 확률이 가장 높은 상자와 겹치는 상자들을 제거하는 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 최댓값을 갖지 않는 상자들을 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 1. 확률 기준으로 모든 상자를 정렬하고 먼저 가장 확률이 높은 상자를 취함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 2. 각 상자에 대해 다른 모든 상자와의 IOU를 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 3. 특정 임곗값을 넘는 상자는 제거&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1pSlD/btsNQwi4Mg5/jZ1V6jQK51pS5au6gyCUD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1pSlD/btsNQwi4Mg5/jZ1V6jQK51pS5au6gyCUD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1pSlD/btsNQwi4Mg5/jZ1V6jQK51pS5au6gyCUD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1pSlD%2FbtsNQwi4Mg5%2FjZ1V6jQK51pS5au6gyCUD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;992&quot; height=&quot;533&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.2 모델 성능 평가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 정밀도(Precision)와 재현율(Recall)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적으로 객체 탐지 모델 평가에 사용되지는 않지만, 다른 지표를 계산하는 기본 지표 역할을 함&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;True&amp;nbsp;Positives(`TP`):&amp;nbsp;예측이&amp;nbsp;동일&amp;nbsp;클래스의&amp;nbsp;실제&amp;nbsp;상자와&amp;nbsp;일치하는지&amp;nbsp;측정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;False&amp;nbsp;Positives(`FP`):&amp;nbsp;예측이&amp;nbsp;실제&amp;nbsp;상자와&amp;nbsp;일치하지&amp;nbsp;않는지&amp;nbsp;측정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;False&amp;nbsp;Negatives(`FN`):&amp;nbsp;실제&amp;nbsp;분류값이&amp;nbsp;그와&amp;nbsp;일치하는&amp;nbsp;예측을&amp;nbsp;갖지&amp;nbsp;못하는지&amp;nbsp;측정 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/saAoq/btsNP9IIqIG/TfVEvOixVUVEAVndbcA5Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/saAoq/btsNP9IIqIG/TfVEvOixVUVEAVndbcA5Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/saAoq/btsNP9IIqIG/TfVEvOixVUVEAVndbcA5Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsaAoq%2FbtsNP9IIqIG%2FTfVEvOixVUVEAVndbcA5Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;46&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Precision&amp;nbsp;:&amp;nbsp;찾았다고&amp;nbsp;주장한&amp;nbsp;경우에&amp;nbsp;대한&amp;nbsp;정확도 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;모델이&amp;nbsp;안정적이지&amp;nbsp;않은&amp;nbsp;특징을&amp;nbsp;기반으로&amp;nbsp;객체&amp;nbsp;존재를&amp;nbsp;예측하면&amp;nbsp;거짓긍정(FP)이&amp;nbsp;많아져서&amp;nbsp;정밀도가&amp;nbsp;낮아짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;존재한다고&amp;nbsp;또는&amp;nbsp;찾았다고&amp;nbsp;긍정적(Positive)으로&amp;nbsp;판단한&amp;nbsp;결과가&amp;nbsp;얼마나&amp;nbsp;정확한가&amp;nbsp;측정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;어떤&amp;nbsp;Object가&amp;nbsp;존재한다고&amp;nbsp;답한경우에&amp;nbsp;대해&amp;nbsp;맞춘&amp;nbsp;경우의&amp;nbsp;비율&amp;nbsp;(&amp;nbsp;존재한다고&amp;nbsp;한&amp;nbsp;주장에&amp;nbsp;대한&amp;nbsp;신뢰도&amp;nbsp;측정의&amp;nbsp;의미)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Recall&amp;nbsp;:&amp;nbsp;존재하는&amp;nbsp;Object중에&amp;nbsp;총&amp;nbsp;몇&amp;nbsp;퍼센트나&amp;nbsp;찾았는지에&amp;nbsp;대한&amp;nbsp;비률 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;모델이&amp;nbsp;너무&amp;nbsp;엄격해서&amp;nbsp;정확한&amp;nbsp;조건을&amp;nbsp;만족할&amp;nbsp;때만&amp;nbsp;객체가&amp;nbsp;탐지된&amp;nbsp;것으로&amp;nbsp;간주하면&amp;nbsp;거짓부정(FN)이&amp;nbsp;많아져서&amp;nbsp;재현율이&amp;nbsp;낮아짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;실제로는&amp;nbsp;존재하는데&amp;nbsp;못&amp;nbsp;찾는&amp;nbsp;경우가&amp;nbsp;얼마나&amp;nbsp;되는지&amp;nbsp;확인하는&amp;nbsp;의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 정밀도-재현율 곡선(Precision-Recall Curve) &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;신뢰도&amp;nbsp;임계값마다&amp;nbsp;모델의&amp;nbsp;정밀도와&amp;nbsp;재현율을&amp;nbsp;시각화 &lt;br /&gt;-&amp;nbsp;모든&amp;nbsp;bounding&amp;nbsp;box와&amp;nbsp;함께&amp;nbsp;모델이&amp;nbsp;예측의&amp;nbsp;정확성을&amp;nbsp;얼마나&amp;nbsp;확실하는지&amp;nbsp;0&amp;nbsp;~&amp;nbsp;1사이의&amp;nbsp;숫자로&amp;nbsp;나타내는&amp;nbsp;신뢰도를&amp;nbsp;출력 &lt;br /&gt;-&amp;nbsp;임계값&amp;nbsp;T에&amp;nbsp;따라&amp;nbsp;정밀도와&amp;nbsp;재현율이&amp;nbsp;달라짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;임계값&amp;nbsp;T&amp;nbsp;이하의&amp;nbsp;예측은&amp;nbsp;제거함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;T가&amp;nbsp;1에&amp;nbsp;가까우면&amp;nbsp;정밀도는&amp;nbsp;높지만&amp;nbsp;재현율은&amp;nbsp;낮음&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;놓치는&amp;nbsp;객체가&amp;nbsp;많아져서&amp;nbsp;재현율이&amp;nbsp;낮아짐.&amp;nbsp;즉,&amp;nbsp;신뢰도가&amp;nbsp;높은&amp;nbsp;예측만&amp;nbsp;유지하기때문에&amp;nbsp;정밀도는&amp;nbsp;높아짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;T가&amp;nbsp;0에&amp;nbsp;가까우면&amp;nbsp;정밀도는&amp;nbsp;낮지만&amp;nbsp;재현율은&amp;nbsp;높음&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;대부분의&amp;nbsp;예측을&amp;nbsp;유지하기때문에&amp;nbsp;재현율은&amp;nbsp;높아지고,&amp;nbsp;거짓긍정(FP)이&amp;nbsp;많아져서&amp;nbsp;정밀도가&amp;nbsp;낮아짐 &lt;br /&gt;-&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;모델이&amp;nbsp;보행자를&amp;nbsp;탐지하고&amp;nbsp;있으면&amp;nbsp;특별한&amp;nbsp;이유없이&amp;nbsp;차를&amp;nbsp;세우더라도&amp;nbsp;어떤&amp;nbsp;보행자도&amp;nbsp;놓치지&amp;nbsp;않도록&amp;nbsp;재현율을&amp;nbsp;높여야&amp;nbsp;함 &lt;br /&gt;-&amp;nbsp;모델이&amp;nbsp;투자&amp;nbsp;기회를&amp;nbsp;탐지하고&amp;nbsp;있다면&amp;nbsp;일부&amp;nbsp;기회를&amp;nbsp;놓치게&amp;nbsp;되더라도&amp;nbsp;잘못된&amp;nbsp;기회에&amp;nbsp;돈을&amp;nbsp;거는&amp;nbsp;일을&amp;nbsp;피하기&amp;nbsp;위해&amp;nbsp;정밀도를&amp;nbsp;높여야&amp;nbsp;함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJTJX/btsNQc6t66c/K4QcgDL7Evp2SwfHk5qHWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kJTJX/btsNQc6t66c/K4QcgDL7Evp2SwfHk5qHWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kJTJX/btsNQc6t66c/K4QcgDL7Evp2SwfHk5qHWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkJTJX%2FbtsNQc6t66c%2FK4QcgDL7Evp2SwfHk5qHWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;417&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) AP (Average Precision, 평균 정밀도) 와 mAP(mean Average Precision) &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;곡선의&amp;nbsp;아래&amp;nbsp;영역에&amp;nbsp;해당 &lt;br /&gt;-&amp;nbsp;항상&amp;nbsp;1x1&amp;nbsp;정사각형으로&amp;nbsp;구성되어&amp;nbsp;있음&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;즉,&amp;nbsp;항상&amp;nbsp;0&amp;nbsp;~&amp;nbsp;1&amp;nbsp;사이의&amp;nbsp;값을&amp;nbsp;가짐 &lt;br /&gt;-&amp;nbsp;단일&amp;nbsp;클래스에&amp;nbsp;대한&amp;nbsp;모델&amp;nbsp;성능&amp;nbsp;정보를&amp;nbsp;제공 &lt;br /&gt;-&amp;nbsp;전역&amp;nbsp;점수를&amp;nbsp;얻기위해서&amp;nbsp;mAP를&amp;nbsp;사용 &lt;br /&gt;-&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;데이터셋이&amp;nbsp;10개의&amp;nbsp;클래스로&amp;nbsp;구성된다면&amp;nbsp;각&amp;nbsp;클래스에&amp;nbsp;대한&amp;nbsp;AP를&amp;nbsp;계산하고,&amp;nbsp;그&amp;nbsp;숫자들의&amp;nbsp;평균을&amp;nbsp;다시&amp;nbsp;구함 &lt;br /&gt;&lt;br /&gt;- mAP 사용 : Object Detection의 성능 평가 지표&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2개의&amp;nbsp;Hyper&amp;nbsp;Parameter&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Confidence&amp;nbsp;Threshold&amp;nbsp;:&amp;nbsp;탐지한&amp;nbsp;객체&amp;nbsp;인식에&amp;nbsp;대한&amp;nbsp;신뢰도로&amp;nbsp;보통&amp;nbsp;0.5&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;IOU&amp;nbsp;Threshold&amp;nbsp;:&amp;nbsp;Precision과&amp;nbsp;Recall로부터&amp;nbsp;계산.&amp;nbsp;Confidence&amp;nbsp;를&amp;nbsp;1.0&amp;nbsp;에서&amp;nbsp;0으로&amp;nbsp;조금씩&amp;nbsp;줄이면서&amp;nbsp;Recall값을&amp;nbsp;0에서&amp;nbsp;1사이에서&amp;nbsp;0.1&amp;nbsp;간격으로&amp;nbsp;11개&amp;nbsp;레벨값에&amp;nbsp;대한&amp;nbsp;Precision&amp;nbsp;값을&amp;nbsp;구해&amp;nbsp;각&amp;nbsp;Recall&amp;nbsp;레벨값에&amp;nbsp;대한&amp;nbsp;Precision&amp;nbsp;값들의&amp;nbsp;평균값&amp;nbsp;구 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;최소&amp;nbsp;2개&amp;nbsp;이상의&amp;nbsp;객체를&amp;nbsp;탐지하는&amp;nbsp;대회인&amp;nbsp;PASCAL&amp;nbsp;Visual&amp;nbsp;Object&amp;nbsp;Classes와&amp;nbsp;Common&amp;nbsp;Objects&amp;nbsp;in&amp;nbsp;Context(COCO)에서&amp;nbsp;mAP가&amp;nbsp;사용됨 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;COCO&amp;nbsp;데이터셋이&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;클래스를&amp;nbsp;포함하고&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;보통&amp;nbsp;Pascal&amp;nbsp;VOC보다&amp;nbsp;점수가&amp;nbsp;더&amp;nbsp;낮게&amp;nbsp;나옴&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQONu9/btsNPZ0AZGy/KvmWf7gdK60qik8jcxyH5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQONu9/btsNPZ0AZGy/KvmWf7gdK60qik8jcxyH5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQONu9/btsNPZ0AZGy/KvmWf7gdK60qik8jcxyH5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQONu9%2FbtsNPZ0AZGy%2FKvmWf7gdK60qik8jcxyH5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;845&quot; height=&quot;254&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.3 데이터셋 (Dataset)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) VOC Dataset&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;PASCAL&amp;nbsp;VOC&amp;nbsp;(시각적&amp;nbsp;객체&amp;nbsp;클래스)&amp;nbsp;데이터&amp;nbsp;세트는&amp;nbsp;잘&amp;nbsp;알려진&amp;nbsp;객체&amp;nbsp;감지,&amp;nbsp;분할&amp;nbsp;및&amp;nbsp;분류&amp;nbsp;데이터&amp;nbsp;세트 &lt;br /&gt;-&amp;nbsp;2005년에서&amp;nbsp;2012년까지&amp;nbsp;진행되었던&amp;nbsp;PASCAL&amp;nbsp;VOC&amp;nbsp;challenge에서&amp;nbsp;쓰이던&amp;nbsp;데이터셋 &lt;br /&gt;-&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;기술의&amp;nbsp;benchmark로&amp;nbsp;간주 &lt;br /&gt;-&amp;nbsp;데이터셋에는&amp;nbsp;20개의&amp;nbsp;클래스가&amp;nbsp;존재 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;aeroplane &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bicycle &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bird &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bottle &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bus &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;car &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chair &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cow &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diningtable &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dog &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;horse &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;motorbike &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pottedplant &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sheep &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sofa &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;train &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tvmonitor &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;훈련&amp;nbsp;및&amp;nbsp;검증&amp;nbsp;데이터&amp;nbsp;:&amp;nbsp;11,530개 &lt;br /&gt;-&amp;nbsp;이미지&amp;nbsp;개수: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;object&amp;nbsp;detection:&amp;nbsp;총&amp;nbsp;9,963개의&amp;nbsp;주석이&amp;nbsp;달린(annotated)&amp;nbsp;이미지가&amp;nbsp;포함.&amp;nbsp;이&amp;nbsp;중에서&amp;nbsp;5,011개가&amp;nbsp;학습&amp;nbsp;데이터 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;segmentation:&amp;nbsp;422개의&amp;nbsp;학습&amp;nbsp;데이터 &lt;br /&gt;-&amp;nbsp;ROI에&amp;nbsp;대한&amp;nbsp;27,450개의&amp;nbsp;Annotation이&amp;nbsp;존재 &lt;br /&gt;-&amp;nbsp;이미지당&amp;nbsp;2.4개의&amp;nbsp;객체&amp;nbsp;존재&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AmGHp/btsNOT7trpT/j5P1dQeiM7hJm6vuXHCQK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AmGHp/btsNOT7trpT/j5P1dQeiM7hJm6vuXHCQK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AmGHp/btsNOT7trpT/j5P1dQeiM7hJm6vuXHCQK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAmGHp%2FbtsNOT7trpT%2Fj5P1dQeiM7hJm6vuXHCQK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;305&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) COCO Dataset&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Common&amp;nbsp;Objects&amp;nbsp;in&amp;nbsp;Context &lt;br /&gt;-&amp;nbsp;200,000개의&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;학습(training)&amp;nbsp;데이터셋:&amp;nbsp;118,000장의&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;검증(validation)&amp;nbsp;데이터셋:&amp;nbsp;5,000장의&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;테스트(test)&amp;nbsp;데이터셋:&amp;nbsp;41,000장의&amp;nbsp;이미지 &lt;br /&gt;-&amp;nbsp;COCO&amp;nbsp;데이터셋의&amp;nbsp;장점 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;다양한&amp;nbsp;크기의&amp;nbsp;물체가&amp;nbsp;존재 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;높은&amp;nbsp;비율로&amp;nbsp;작은&amp;nbsp;물체들이&amp;nbsp;존재 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Object들이&amp;nbsp;혼잡하게&amp;nbsp;존재하고,&amp;nbsp;occlusion(폐색)이&amp;nbsp;많이&amp;nbsp;존재 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;덜&amp;nbsp;iconic&amp;nbsp;합니다.&amp;nbsp;여기서&amp;nbsp;iconic의&amp;nbsp;의미는&amp;nbsp;이미지가&amp;nbsp;특정&amp;nbsp;카테고리에&amp;nbsp;명확하게&amp;nbsp;속해있는&amp;nbsp;경우를&amp;nbsp;말합니다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;아래&amp;nbsp;이미지의&amp;nbsp;(a)의&amp;nbsp;이미지들은&amp;nbsp;누가봐도&amp;nbsp;명확하게&amp;nbsp;개,&amp;nbsp;소&amp;nbsp;등의&amp;nbsp;명확하게&amp;nbsp;특정&amp;nbsp;카테고리에&amp;nbsp;속한걸&amp;nbsp;누구나&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;(b)의&amp;nbsp;이미지들은&amp;nbsp;(a)&amp;nbsp;보다는&amp;nbsp;모호하지만,&amp;nbsp;특정&amp;nbsp;카테고리에&amp;nbsp;속하다고&amp;nbsp;말할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;그런데&amp;nbsp;(c)의&amp;nbsp;경우&amp;nbsp;어떤&amp;nbsp;카테고리에&amp;nbsp;속하는지&amp;nbsp;분류하기가&amp;nbsp;모호합니다.&amp;nbsp;현실세계&amp;nbsp;사진에서는&amp;nbsp;(a)나&amp;nbsp;(b)보단&amp;nbsp;(c)에&amp;nbsp;속하는&amp;nbsp;경우가&amp;nbsp;훨씬&amp;nbsp;많이&amp;nbsp;존재합니다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;80개의&amp;nbsp;카테고리에&amp;nbsp;500,000개&amp;nbsp;이상의&amp;nbsp;객체&amp;nbsp;Annotation이&amp;nbsp;존재 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bicycle &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;car &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;motorbike &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;aeroplane &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bus &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;train &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;truck &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;traffic&amp;nbsp;light &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fire&amp;nbsp;hydrant &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stop&amp;nbsp;sign &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parking&amp;nbsp;meter &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bench &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bird &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dog &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;horse &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sheep &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cow &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elephant &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bear &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;zebra &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;giraffe &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;backpack &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;umbrella &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handbag &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tie &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;suitcase &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frisbee &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;skis &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;snowboard &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sports&amp;nbsp;ball &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kite &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;baseball&amp;nbsp;bat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;baseball&amp;nbsp;glove &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;skateboard &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;surfboard &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tennis&amp;nbsp;racket &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bottle &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wine&amp;nbsp;glass &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cup &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fork &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;knife &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spoon &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bowl &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;banana &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;apple &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sandwich &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;orange &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;broccoli &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carrot &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hot&amp;nbsp;dog &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pizza &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;donut &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cake &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chair &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sofa &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pottedplant &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bed &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diningtable &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;toilet &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tvmonitor &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;laptop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mouse &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;remote &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyboard &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cell&amp;nbsp;phone &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;microwave &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oven &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;toaster &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sink &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refrigerator &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;book &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clock &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vase &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scissors &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;teddy&amp;nbsp;bear &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hair&amp;nbsp;drier &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;toothbrush &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;-&amp;nbsp;&lt;a href=&quot;https://cocodataset.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cocodataset.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEAlFb/btsNQvR0619/cKIKyrEtfl6DjGQkktfAR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEAlFb/btsNQvR0619/cKIKyrEtfl6DjGQkktfAR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEAlFb/btsNQvR0619/cKIKyrEtfl6DjGQkktfAR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEAlFb%2FbtsNQvR0619%2FcKIKyrEtfl6DjGQkktfAR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;793&quot; height=&quot;238&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 객체 탐지의 역사&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GZ9ht/btsNPXV5dKK/8gklowTo3g0UiZK0BA9AKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GZ9ht/btsNPXV5dKK/8gklowTo3g0UiZK0BA9AKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GZ9ht/btsNPXV5dKK/8gklowTo3g0UiZK0BA9AKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGZ9ht%2FbtsNPXV5dKK%2F8gklowTo3g0UiZK0BA9AKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1169&quot; height=&quot;594&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&amp;nbsp;RCNN&amp;nbsp;(2013) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Rich&amp;nbsp;feature&amp;nbsp;hierarchies&amp;nbsp;for&amp;nbsp;accurate&amp;nbsp;object&amp;nbsp;detection&amp;nbsp;and&amp;nbsp;semantic&amp;nbsp;segmentation&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1311.2524)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1311.2524)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;물체&amp;nbsp;검출에&amp;nbsp;사용된&amp;nbsp;기존&amp;nbsp;방식인&amp;nbsp;sliding&amp;nbsp;window는&amp;nbsp;background를&amp;nbsp;검출하는&amp;nbsp;소요되는&amp;nbsp;시간이&amp;nbsp;많았는데,&amp;nbsp;이를&amp;nbsp;개선시킨&amp;nbsp;기법으로&amp;nbsp;Region&amp;nbsp;Proposal&amp;nbsp;방식&amp;nbsp;제안 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;매우&amp;nbsp;높은&amp;nbsp;Detection이&amp;nbsp;가능하지만,&amp;nbsp;복잡한&amp;nbsp;아키텍처&amp;nbsp;및&amp;nbsp;학습&amp;nbsp;프로세스로&amp;nbsp;인해&amp;nbsp;Detection&amp;nbsp;시간이&amp;nbsp;매우&amp;nbsp;오래&amp;nbsp;걸림 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;SPP&amp;nbsp;Net&amp;nbsp;(2014) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Spatial&amp;nbsp;Pyramid&amp;nbsp;Pooling&amp;nbsp;in&amp;nbsp;Deep&amp;nbsp;Convolutional&amp;nbsp;Networks&amp;nbsp;for&amp;nbsp;Visual&amp;nbsp;Recognition&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1406.4729)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1406.4729)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RCNN의&amp;nbsp;문제를&amp;nbsp;Selective&amp;nbsp;search로&amp;nbsp;해결하려&amp;nbsp;했지만,&amp;nbsp;bounding&amp;nbsp;box의&amp;nbsp;크기가&amp;nbsp;제각각인&amp;nbsp;문제가&amp;nbsp;있어서&amp;nbsp;FC&amp;nbsp;Input에&amp;nbsp;고정된&amp;nbsp;사이즈로&amp;nbsp;제공하기&amp;nbsp;위한&amp;nbsp;방법&amp;nbsp;제안 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SPP은&amp;nbsp;RCNN에서&amp;nbsp;conv&amp;nbsp;layer와&amp;nbsp;fc&amp;nbsp;layer사이에&amp;nbsp;위치하여&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;feature&amp;nbsp;map에&amp;nbsp;투영된&amp;nbsp;이미지를&amp;nbsp;고정된&amp;nbsp;값으로&amp;nbsp;풀링 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SPP를&amp;nbsp;이용해&amp;nbsp;RCNN에&amp;nbsp;비해&amp;nbsp;실행시간을&amp;nbsp;매우&amp;nbsp;단축시킴 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;Fast&amp;nbsp;RCNN&amp;nbsp;(2015) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Fast&amp;nbsp;R-CNN&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1504.08083)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1504.08083)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SPP&amp;nbsp;layer를&amp;nbsp;ROI&amp;nbsp;pooling으로&amp;nbsp;바꿔서&amp;nbsp;7x7&amp;nbsp;layer&amp;nbsp;1개로&amp;nbsp;해결 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SVM을&amp;nbsp;softmax로&amp;nbsp;대체하여&amp;nbsp;Classification&amp;nbsp;과&amp;nbsp;Regression&amp;nbsp;Loss를&amp;nbsp;함께&amp;nbsp;반영한&amp;nbsp;Multi&amp;nbsp;task&amp;nbsp;Loss&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ROI&amp;nbsp;Pooling을&amp;nbsp;이용해&amp;nbsp;SPP보다&amp;nbsp;간단하고,&amp;nbsp;RCNN에&amp;nbsp;비해&amp;nbsp;수행시간을&amp;nbsp;많이&amp;nbsp;줄임 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;Fater&amp;nbsp;RCNN(2015) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Faster&amp;nbsp;R-CNN:&amp;nbsp;Towards&amp;nbsp;Real-Time&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;with&amp;nbsp;Region&amp;nbsp;Proposal&amp;nbsp;Networks&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1506.01497)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1506.01497)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RPN(Region&amp;nbsp;proposal&amp;nbsp;network)&amp;nbsp;+&amp;nbsp;Fast&amp;nbsp;RCNN&amp;nbsp;방식 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Selective&amp;nbsp;Search를&amp;nbsp;대체하기&amp;nbsp;위한&amp;nbsp;Region&amp;nbsp;Proposal&amp;nbsp;Network구현 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RPN도&amp;nbsp;학습시켜서&amp;nbsp;전체를&amp;nbsp;end-to-end로&amp;nbsp;학습&amp;nbsp;가능&amp;nbsp;(GPU사용&amp;nbsp;가능) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Region&amp;nbsp;Proposal를&amp;nbsp;위해&amp;nbsp;Object가&amp;nbsp;있는지&amp;nbsp;없는지의&amp;nbsp;후보&amp;nbsp;Box인&amp;nbsp;Anchor&amp;nbsp;Box&amp;nbsp;개념&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Anchor&amp;nbsp;Box를&amp;nbsp;도입해&amp;nbsp;FastRCNN에&amp;nbsp;비해&amp;nbsp;정확도를&amp;nbsp;높이고&amp;nbsp;속도를&amp;nbsp;향상시킴 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;SSD&amp;nbsp;(2015) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SSD:&amp;nbsp;Single&amp;nbsp;Shot&amp;nbsp;MultiBox&amp;nbsp;Detector&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1512.02325)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1512.02325)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Faster-RCNN은&amp;nbsp;region&amp;nbsp;proposal과&amp;nbsp;anchor&amp;nbsp;box를&amp;nbsp;이용한&amp;nbsp;검출의&amp;nbsp;2단계를&amp;nbsp;걸치는&amp;nbsp;과정에서&amp;nbsp;시간이&amp;nbsp;필요해&amp;nbsp;real-time(20~30&amp;nbsp;fps)으로는&amp;nbsp;어려움 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SSD는&amp;nbsp;Feature&amp;nbsp;map의&amp;nbsp;size를&amp;nbsp;조정하고,&amp;nbsp;동시에&amp;nbsp;앵커박스를&amp;nbsp;같이&amp;nbsp;적용함으로써&amp;nbsp;1&amp;nbsp;shot으로&amp;nbsp;물체&amp;nbsp;검출이&amp;nbsp;가능 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;real-time으로&amp;nbsp;사용할&amp;nbsp;정도의&amp;nbsp;성능을&amp;nbsp;갖춤&amp;nbsp;(30~40&amp;nbsp;fps) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;작은&amp;nbsp;이미지의&amp;nbsp;경우에&amp;nbsp;잘&amp;nbsp;인식하지&amp;nbsp;못하는&amp;nbsp;경우가&amp;nbsp;생겨서&amp;nbsp;data&amp;nbsp;augmentation을&amp;nbsp;통해&amp;nbsp;mAP를&amp;nbsp;63에서&amp;nbsp;74로&amp;nbsp;비약적으로&amp;nbsp;높임 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;RetinaNet&amp;nbsp;(2017) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Focal&amp;nbsp;Loss&amp;nbsp;for&amp;nbsp;Dense&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1708.02002)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1708.02002)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RetinaNet이전에는&amp;nbsp;1-shot&amp;nbsp;detection과&amp;nbsp;2-shot&amp;nbsp;detection의&amp;nbsp;차이가&amp;nbsp;극명하게&amp;nbsp;나뉘어&amp;nbsp;속도를&amp;nbsp;선택하면&amp;nbsp;정확도를&amp;nbsp;trade-off&amp;nbsp;할&amp;nbsp;수&amp;nbsp;밖에&amp;nbsp;없는&amp;nbsp;상황 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RetinaNet은&amp;nbsp;Focal&amp;nbsp;Loss라는&amp;nbsp;개념의&amp;nbsp;도입과&amp;nbsp;FPN&amp;nbsp;덕분에&amp;nbsp;기존&amp;nbsp;모델들보다&amp;nbsp;정확도도&amp;nbsp;높고&amp;nbsp;속도도&amp;nbsp;여타&amp;nbsp;1-shot&amp;nbsp;detector와&amp;nbsp;비견되는&amp;nbsp;모델 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Detection에선&amp;nbsp;검출하고&amp;nbsp;싶은&amp;nbsp;물체와&amp;nbsp;(foreground&amp;nbsp;object)&amp;nbsp;검출할&amp;nbsp;필요가&amp;nbsp;없는&amp;nbsp;배경&amp;nbsp;물체들이&amp;nbsp;있는데&amp;nbsp;(background&amp;nbsp;object)&amp;nbsp;배경&amp;nbsp;물체의&amp;nbsp;숫자가&amp;nbsp;매우&amp;nbsp;많을&amp;nbsp;경우&amp;nbsp;배경&amp;nbsp;Loss를&amp;nbsp;적게&amp;nbsp;하더라도&amp;nbsp;숫자에&amp;nbsp;압도되어&amp;nbsp;배경의&amp;nbsp;Loss의&amp;nbsp;총합을&amp;nbsp;학습해버림&amp;nbsp;(예를&amp;nbsp;들어,&amp;nbsp;숲을&amp;nbsp;배경으로&amp;nbsp;하는&amp;nbsp;사람을&amp;nbsp;검출해야하는데&amp;nbsp;배경의&amp;nbsp;나무가&amp;nbsp;100개나&amp;nbsp;되다보니&amp;nbsp;사람의&amp;nbsp;특징이&amp;nbsp;아닌&amp;nbsp;나무가&amp;nbsp;있는&amp;nbsp;배경을&amp;nbsp;학습해버림) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Focal&amp;nbsp;Loss는&amp;nbsp;이런&amp;nbsp;문제를&amp;nbsp;기존의&amp;nbsp;crossentropy&amp;nbsp;함수에서&amp;nbsp;(1-sig)을&amp;nbsp;제곱하여&amp;nbsp;background&amp;nbsp;object의&amp;nbsp;loss를&amp;nbsp;현저히&amp;nbsp;줄여버리는&amp;nbsp;방법으로&amp;nbsp;loss를&amp;nbsp;변동시켜&amp;nbsp;해결 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Focal&amp;nbsp;Loss를&amp;nbsp;통해&amp;nbsp;검출하고자&amp;nbsp;하는&amp;nbsp;물체와&amp;nbsp;관련이&amp;nbsp;없는&amp;nbsp;background&amp;nbsp;object들은&amp;nbsp;학습에&amp;nbsp;영향을&amp;nbsp;주지&amp;nbsp;않게&amp;nbsp;되고,&amp;nbsp;학습의&amp;nbsp;다양성이&amp;nbsp;더&amp;nbsp;넓어짐&amp;nbsp;(작은&amp;nbsp;물체,&amp;nbsp;큰&amp;nbsp;물체에&amp;nbsp;구애받지&amp;nbsp;않고&amp;nbsp;검출할&amp;nbsp;수&amp;nbsp;있게됨) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;실제로&amp;nbsp;RetinaNet은&amp;nbsp;object&amp;nbsp;proposal을&amp;nbsp;2000개나&amp;nbsp;실시하여&amp;nbsp;이를&amp;nbsp;확인 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;Mask&amp;nbsp;R-CNN&amp;nbsp;(2018) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Mask&amp;nbsp;R-CNN&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/pdf/1703.06870.pdf)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/1703.06870.pdf)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;YOLO&amp;nbsp;(2018) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv3:&amp;nbsp;An&amp;nbsp;Incremental&amp;nbsp;Improvement&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/abs/1804.02767)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1804.02767)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLO는&amp;nbsp;v1,&amp;nbsp;v2,&amp;nbsp;v3의&amp;nbsp;순서로&amp;nbsp;발전하였는데,&amp;nbsp;v1은&amp;nbsp;정확도가&amp;nbsp;너무&amp;nbsp;낮은&amp;nbsp;문제가&amp;nbsp;있었고&amp;nbsp;이&amp;nbsp;문제는&amp;nbsp;v2까지&amp;nbsp;이어짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;엔지니어링적으로&amp;nbsp;보완한&amp;nbsp;v3는&amp;nbsp;v2보다&amp;nbsp;살짝&amp;nbsp;속도는&amp;nbsp;떨어지더라도&amp;nbsp;정확도를&amp;nbsp;대폭&amp;nbsp;높인&amp;nbsp;모델 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RetinaNet과&amp;nbsp;마찬가지로&amp;nbsp;FPN을&amp;nbsp;도입해&amp;nbsp;정확도를&amp;nbsp;높임 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RetinaNet에&amp;nbsp;비하면&amp;nbsp;정확도는&amp;nbsp;4mAP정도&amp;nbsp;떨어지지만,&amp;nbsp;속도는&amp;nbsp;더&amp;nbsp;빠르다는&amp;nbsp;장점 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;RefineDet&amp;nbsp;(2018) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Single-Shot&amp;nbsp;Refinement&amp;nbsp;Neural&amp;nbsp;Network&amp;nbsp;for&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/pdf/1711.06897.pdf)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/1711.06897.pdf)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;M2Det&amp;nbsp;(2019) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;M2Det:&amp;nbsp;A&amp;nbsp;Single-Shot&amp;nbsp;Object&amp;nbsp;Detector&amp;nbsp;based&amp;nbsp;on&amp;nbsp;Multi-Level&amp;nbsp;Feature&amp;nbsp;Pyramid&amp;nbsp;Network&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/pdf/1811.04533.pdf)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/1811.04533.pdf)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;EfficientDet&amp;nbsp;(2019) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;EfficientDet:&amp;nbsp;Scalable&amp;nbsp;and&amp;nbsp;Efficient&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/pdf/1911.09070v1.pdf)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/1911.09070v1.pdf)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;YOLOv4&amp;nbsp;(2020) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv4:&amp;nbsp;Optimal&amp;nbsp;Speed&amp;nbsp;and&amp;nbsp;Accuracy&amp;nbsp;of&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;(&lt;a href=&quot;https://arxiv.org/pdf/2004.10934v1.pdf)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/pdf/2004.10934v1.pdf)&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv3에&amp;nbsp;비해&amp;nbsp;AP,&amp;nbsp;FPS가&amp;nbsp;각각&amp;nbsp;10%,&amp;nbsp;12%&amp;nbsp;증가 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv3와&amp;nbsp;다른&amp;nbsp;개발자인&amp;nbsp;AlexeyBochkousky가&amp;nbsp;발표 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;v3에서&amp;nbsp;다양한&amp;nbsp;딥러닝&amp;nbsp;기법(WRC,&amp;nbsp;CSP&amp;nbsp;...)&amp;nbsp;등을&amp;nbsp;사용해&amp;nbsp;성능을&amp;nbsp;향상시킴 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;CSPNet&amp;nbsp;기반의&amp;nbsp;backbone(CSPDarkNet53)을&amp;nbsp;설계하여&amp;nbsp;사용 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;YOLOv5&amp;nbsp;(2020) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv4에&amp;nbsp;비해&amp;nbsp;낮은&amp;nbsp;용량과&amp;nbsp;빠른&amp;nbsp;속도&amp;nbsp;(성능은&amp;nbsp;비슷) &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv4와&amp;nbsp;같은&amp;nbsp;CSPNet&amp;nbsp;기반의&amp;nbsp;backbone을&amp;nbsp;설계하여&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YOLOv3를&amp;nbsp;PyTorch로&amp;nbsp;implementation한&amp;nbsp;GlennJocher가&amp;nbsp;발표 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Darknet이&amp;nbsp;아닌&amp;nbsp;PyTorch&amp;nbsp;구현이기&amp;nbsp;때문에,&amp;nbsp;이전&amp;nbsp;버전들과&amp;nbsp;다르다고&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;이후 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;수&amp;nbsp;많은&amp;nbsp;YOLO&amp;nbsp;버전들이&amp;nbsp;탄생 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Object&amp;nbsp;Detection&amp;nbsp;분야의&amp;nbsp;논문들이&amp;nbsp;계속해서&amp;nbsp;나오고&amp;nbsp;있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 객체 탐지 아키텍처&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1157&quot; data-origin-height=&quot;663&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G4RQE/btsNPCKZOU3/mWmKlkoZeDaAqgJM9SHpk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G4RQE/btsNPCKZOU3/mWmKlkoZeDaAqgJM9SHpk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G4RQE/btsNPCKZOU3/mWmKlkoZeDaAqgJM9SHpk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG4RQE%2FbtsNPCKZOU3%2FmWmKlkoZeDaAqgJM9SHpk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1157&quot; height=&quot;663&quot; data-origin-width=&quot;1157&quot; data-origin-height=&quot;663&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Two&amp;nbsp;Stage&amp;nbsp;Detector:&amp;nbsp;object가&amp;nbsp;있을&amp;nbsp;법한&amp;nbsp;위치의&amp;nbsp;후보(proposals)들을&amp;nbsp;뽑아내는&amp;nbsp;단계,&amp;nbsp;이후&amp;nbsp;실제로&amp;nbsp;object가&amp;nbsp;있는지를&amp;nbsp;Classification과&amp;nbsp;정확한&amp;nbsp;바운딩&amp;nbsp;박스를&amp;nbsp;구하는&amp;nbsp;Regression을&amp;nbsp;수행하는&amp;nbsp;단계가&amp;nbsp;분리되어&amp;nbsp;있음.&amp;nbsp;예:Faster-RCNN &lt;br /&gt;-&amp;nbsp;One&amp;nbsp;Stage&amp;nbsp;Detector:객체의&amp;nbsp;검출과&amp;nbsp;분류,&amp;nbsp;그리고&amp;nbsp;바운딩박스&amp;nbsp;regression을&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;하는&amp;nbsp;방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt; 전통적인 객체 탐지 기법 - 영역 제안(Region Proposal) 기법 &amp;gt; &lt;br /&gt;-&amp;nbsp;Sliding&amp;nbsp;Window&amp;nbsp;기법&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5zTud/btsNPgBotzD/xFgBHvuVIegLctz6EygIqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5zTud/btsNPgBotzD/xFgBHvuVIegLctz6EygIqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5zTud/btsNPgBotzD/xFgBHvuVIegLctz6EygIqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5zTud%2FbtsNPgBotzD%2FxFgBHvuVIegLctz6EygIqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;251&quot; height=&quot;367&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지를&amp;nbsp;다양한&amp;nbsp;크기의&amp;nbsp;창(window)으로&amp;nbsp;스캔하면서&amp;nbsp;각&amp;nbsp;위치에서&amp;nbsp;객체가&amp;nbsp;있는지&amp;nbsp;분류하는&amp;nbsp;방식&amp;nbsp;(검출하고자&amp;nbsp;하는&amp;nbsp;입력&amp;nbsp;이미지에&amp;nbsp;정해진&amp;nbsp;크기의&amp;nbsp;Bounding&amp;nbsp;Box를&amp;nbsp;만들어&amp;nbsp;방향을&amp;nbsp;이동하면서&amp;nbsp;물체가&amp;nbsp;있을&amp;nbsp;법한&amp;nbsp;box나&amp;nbsp;영역을&amp;nbsp;추출하는&amp;nbsp;것) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;모든&amp;nbsp;영역을&amp;nbsp;탐색해야&amp;nbsp;하기&amp;nbsp;때문에&amp;nbsp;시간이&amp;nbsp;많이&amp;nbsp;소요되어&amp;nbsp;비효율적이라는&amp;nbsp;특성이&amp;nbsp;있습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지를&amp;nbsp;가로&amp;nbsp;질러&amp;nbsp;고정&amp;nbsp;된&amp;nbsp;크기의&amp;nbsp;window를&amp;nbsp;여러&amp;nbsp;배율로&amp;nbsp;슬라이드하는&amp;nbsp;것을&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있음.&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이러한&amp;nbsp;각&amp;nbsp;단계에서&amp;nbsp;window가&amp;nbsp;중지되고&amp;nbsp;일부&amp;nbsp;feature를&amp;nbsp;계산한&amp;nbsp;다음&amp;nbsp;영역을&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;분류 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이&amp;nbsp;영역에&amp;nbsp;얼굴이&amp;nbsp;포함되어&amp;nbsp;있습니다&amp;nbsp;&amp;agrave;&amp;nbsp;Yes &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이&amp;nbsp;영역에&amp;nbsp;얼굴이&amp;nbsp;포함되어&amp;nbsp;있지&amp;nbsp;않습니다&amp;nbsp;&amp;agrave;&amp;nbsp;No &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[작동&amp;nbsp;방식] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.&amp;nbsp;창&amp;nbsp;생성:&amp;nbsp;다양한&amp;nbsp;크기와&amp;nbsp;비율(예:&amp;nbsp;64&amp;times;64,&amp;nbsp;128&amp;times;128&amp;nbsp;등)의&amp;nbsp;탐색&amp;nbsp;창을&amp;nbsp;준비합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2.&amp;nbsp;슬라이딩&amp;nbsp;과정:&amp;nbsp;각&amp;nbsp;창을&amp;nbsp;일정&amp;nbsp;스텝(보통&amp;nbsp;4~8픽셀)씩&amp;nbsp;이동하며&amp;nbsp;이미지&amp;nbsp;전체를&amp;nbsp;스캔합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3.&amp;nbsp;특징&amp;nbsp;추출:&amp;nbsp;각&amp;nbsp;창에서&amp;nbsp;HOG(Histogram&amp;nbsp;of&amp;nbsp;Oriented&amp;nbsp;Gradients),&amp;nbsp;SIFT&amp;nbsp;등의&amp;nbsp;특징을&amp;nbsp;추출합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4.&amp;nbsp;분류:&amp;nbsp;SVM(Support&amp;nbsp;Vector&amp;nbsp;Machine)이나&amp;nbsp;AdaBoost&amp;nbsp;같은&amp;nbsp;분류기로&amp;nbsp;각&amp;nbsp;창에&amp;nbsp;객체가&amp;nbsp;있는지&amp;nbsp;판단합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5.&amp;nbsp;후처리:&amp;nbsp;NMS(Non-Maximum&amp;nbsp;Suppression)를&amp;nbsp;적용해&amp;nbsp;중복&amp;nbsp;검출을&amp;nbsp;제거합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;gt;&amp;nbsp;계산&amp;nbsp;복잡도:&amp;nbsp;이미지&amp;nbsp;크기&amp;nbsp;&amp;times;&amp;nbsp;창&amp;nbsp;크기&amp;nbsp;종류&amp;nbsp;&amp;times;&amp;nbsp;스케일&amp;nbsp;수&amp;nbsp;&amp;rarr;&amp;nbsp;수만~수십만&amp;nbsp;번의&amp;nbsp;분류&amp;nbsp;연산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Selective&amp;nbsp;Search&amp;nbsp;(SS)&amp;nbsp;기법&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIHz9R/btsNQ2PlhTl/AC9nPtpsmMghNEBskcfI41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIHz9R/btsNQ2PlhTl/AC9nPtpsmMghNEBskcfI41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIHz9R/btsNQ2PlhTl/AC9nPtpsmMghNEBskcfI41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIHz9R%2FbtsNQ2PlhTl%2FAC9nPtpsmMghNEBskcfI41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1115&quot; height=&quot;475&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지의&amp;nbsp;특성(색상,&amp;nbsp;질감,&amp;nbsp;크기&amp;nbsp;등)을&amp;nbsp;고려해&amp;nbsp;객체가&amp;nbsp;있을&amp;nbsp;법한&amp;nbsp;영역(Region&amp;nbsp;Proposal)을&amp;nbsp;먼저&amp;nbsp;제안하고,&amp;nbsp;그&amp;nbsp;영역들만&amp;nbsp;분류하는&amp;nbsp;방식입니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Selective&amp;nbsp;Search(SS)는&amp;nbsp;색상,&amp;nbsp;질감&amp;nbsp;및&amp;nbsp;모양과&amp;nbsp;같은&amp;nbsp;다양한&amp;nbsp;하위&amp;nbsp;수준&amp;nbsp;이미지&amp;nbsp;기능을&amp;nbsp;결합하여&amp;nbsp;이미지&amp;nbsp;영역의&amp;nbsp;계층적&amp;nbsp;그룹을&amp;nbsp;만드는 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;방식으로&amp;nbsp;작동 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[작동방식] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.&amp;nbsp;초기&amp;nbsp;분할:&amp;nbsp;이미지를&amp;nbsp;작은&amp;nbsp;초기&amp;nbsp;영역들로&amp;nbsp;과분할합니다(약&amp;nbsp;2,000개&amp;nbsp;정도). &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2.&amp;nbsp;유사도&amp;nbsp;계산:&amp;nbsp;인접&amp;nbsp;영역&amp;nbsp;간&amp;nbsp;색상,&amp;nbsp;질감,&amp;nbsp;크기,&amp;nbsp;형태&amp;nbsp;유사도를&amp;nbsp;계산합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3.&amp;nbsp;영역&amp;nbsp;병합:&amp;nbsp;유사도가&amp;nbsp;가장&amp;nbsp;높은&amp;nbsp;영역들부터&amp;nbsp;점진적으로&amp;nbsp;병합합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4.&amp;nbsp;후보&amp;nbsp;영역&amp;nbsp;생성:&amp;nbsp;병합&amp;nbsp;과정에서&amp;nbsp;생성된&amp;nbsp;모든&amp;nbsp;영역들을&amp;nbsp;객체&amp;nbsp;후보(약&amp;nbsp;2,000개)로&amp;nbsp;간주합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5.&amp;nbsp;분류:&amp;nbsp;각&amp;nbsp;후보&amp;nbsp;영역에서&amp;nbsp;특징을&amp;nbsp;추출하고&amp;nbsp;분류기를&amp;nbsp;적용해&amp;nbsp;객체&amp;nbsp;여부를&amp;nbsp;판단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. YOLO (You Only Look Once)&lt;br /&gt;-&amp;nbsp;&lt;a href=&quot;https://www.ultralytics.com/ko/yolo&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ultralytics.com/ko/yolo&lt;/a&gt;&amp;nbsp;:&amp;nbsp;테스트해보기 &lt;br /&gt;-&amp;nbsp;&lt;a href=&quot;https://velog.io/@choonsik_mom/Object-Detection-with-yolo-NAS-zpetis4o&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@choonsik_mom/Object-Detection-with-yolo-NAS-zpetis4o&lt;/a&gt;&amp;nbsp;성능비 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;2015년&amp;nbsp;Joseph&amp;nbsp;Redmon&amp;nbsp;이&amp;nbsp;아키텍처를&amp;nbsp;논문과&amp;nbsp;함께&amp;nbsp;발표함,&amp;nbsp;가장&amp;nbsp;빠른&amp;nbsp;객체&amp;nbsp;검출&amp;nbsp;알고리즘&amp;nbsp;중&amp;nbsp;하나 &lt;br /&gt;-&amp;nbsp;Yolo&amp;nbsp;형식&amp;nbsp;:&amp;nbsp;클래스&amp;nbsp;번호|x의&amp;nbsp;center좌표|y의&amp;nbsp;center좌표|너비|높이 &lt;br /&gt;-&amp;nbsp;256x256&amp;nbsp;사이즈의&amp;nbsp;이미지 &lt;br /&gt;-&amp;nbsp;Yolov4까지는&amp;nbsp;파이썬,&amp;nbsp;텐서플로&amp;nbsp;기반&amp;nbsp;프레임워크가&amp;nbsp;아닌&amp;nbsp;C++로&amp;nbsp;구현된&amp;nbsp;코드&amp;nbsp;기준&amp;nbsp;GPU&amp;nbsp;사용&amp;nbsp;시,&amp;nbsp;초당&amp;nbsp;170&amp;nbsp;프레임(170&amp;nbsp;FPS,&amp;nbsp;frames&amp;nbsp;per&amp;nbsp;second),&amp;nbsp;Yolov5부터는&amp;nbsp;&amp;nbsp;PyTorch로&amp;nbsp;개발이&amp;nbsp;이루어져&amp;nbsp;2023년&amp;nbsp;현재&amp;nbsp;빠른속도,&amp;nbsp;사용자&amp;nbsp;친화적인&amp;nbsp;파이썬&amp;nbsp;인터페이스를&amp;nbsp;제공하는&amp;nbsp;Yolov8&amp;nbsp;(SOFA)&amp;nbsp;아키텍처로&amp;nbsp;진화 &lt;br /&gt;-&amp;nbsp;작은&amp;nbsp;크기의&amp;nbsp;물체를&amp;nbsp;탐지하는데는&amp;nbsp;어려움 &lt;br /&gt;[작동&amp;nbsp;방식] &lt;br /&gt;1.&amp;nbsp;그리드&amp;nbsp;분할:&amp;nbsp;이미지를&amp;nbsp;S&amp;times;S&amp;nbsp;그리드(일반적으로&amp;nbsp;7&amp;times;7&amp;nbsp;또는&amp;nbsp;13&amp;times;13)로&amp;nbsp;분할합니다. &lt;br /&gt;2.&amp;nbsp;네트워크&amp;nbsp;구조:&amp;nbsp;단일&amp;nbsp;CNN(Convolutional&amp;nbsp;Neural&amp;nbsp;Network)을&amp;nbsp;통과시켜&amp;nbsp;전체&amp;nbsp;이미지의&amp;nbsp;특징을&amp;nbsp;추출합니다. &lt;br /&gt;3.&amp;nbsp;예측&amp;nbsp;값: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;그리드&amp;nbsp;셀마다&amp;nbsp;B개의&amp;nbsp;바운딩&amp;nbsp;박스를&amp;nbsp;예측 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;바운딩&amp;nbsp;박스는&amp;nbsp;5개&amp;nbsp;값(x,&amp;nbsp;y,&amp;nbsp;w,&amp;nbsp;h,&amp;nbsp;confidence)&amp;nbsp;포함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;그리드&amp;nbsp;셀에서&amp;nbsp;C개&amp;nbsp;클래스의&amp;nbsp;조건부&amp;nbsp;확률&amp;nbsp;예측 &lt;br /&gt;4.&amp;nbsp;출력&amp;nbsp;형태:&amp;nbsp;S&amp;times;S&amp;times;(5B+C)&amp;nbsp;텐서 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;예:&amp;nbsp;7&amp;times;7&amp;nbsp;그리드,&amp;nbsp;2개&amp;nbsp;바운딩&amp;nbsp;박스,&amp;nbsp;20개&amp;nbsp;클래스&amp;nbsp;&amp;rarr;&amp;nbsp;7&amp;times;7&amp;times;30&amp;nbsp;텐서 &lt;br /&gt;5.&amp;nbsp;후처리:&amp;nbsp;낮은&amp;nbsp;신뢰도의&amp;nbsp;박스&amp;nbsp;제거&amp;nbsp;및&amp;nbsp;NMS&amp;nbsp;적용 &lt;br /&gt;&lt;br /&gt;=&amp;nbsp;&amp;gt;&amp;nbsp;특징:&amp;nbsp;전체&amp;nbsp;이미지를&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;처리하므로&amp;nbsp;매우&amp;nbsp;빠르며(초당&amp;nbsp;45~155프레임),&amp;nbsp;객체의&amp;nbsp;전체적인&amp;nbsp;컨텍스트를&amp;nbsp;고려할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.1 YOLO 아키텍처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 백본 모델(backbone model) 기반&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특징 추출기(Feature Extractor)라고도 불림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- YOLO는 자체 맞춤 아키텍처 사용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;953&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMd66s/btsNPE21HlW/g9t8N2vFsi7YumugeTfGM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMd66s/btsNPE21HlW/g9t8N2vFsi7YumugeTfGM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMd66s/btsNPE21HlW/g9t8N2vFsi7YumugeTfGM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMd66s%2FbtsNPE21HlW%2Fg9t8N2vFsi7YumugeTfGM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1161&quot; height=&quot;953&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;953&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 어떤 특징 추출기 아키텍처를 사용했는지에 따라 성능 달라짐&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caNHhN/btsNQXUOGwe/iu7LTcucTXJnNQGxXFuYe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caNHhN/btsNQXUOGwe/iu7LTcucTXJnNQGxXFuYe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caNHhN/btsNQXUOGwe/iu7LTcucTXJnNQGxXFuYe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaNHhN%2FbtsNQXUOGwe%2Fiu7LTcucTXJnNQGxXFuYe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;846&quot; height=&quot;235&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 마지막 계층은 크기가 w x h x D인 특징 볼륨 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- w x h는 그리드의 크기이고 D는 특징 볼륨 깊이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.2 YOLO 계층 출력 &lt;br /&gt;&lt;br /&gt;- 마지막 계층 출력은 w x h x M 행렬 &lt;br /&gt;&amp;nbsp;&amp;nbsp;- M = B x (C&amp;nbsp; + 5)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;B&amp;nbsp;:&amp;nbsp;그리드&amp;nbsp;셀당&amp;nbsp;경계&amp;nbsp;상자&amp;nbsp;개수 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;C&amp;nbsp;:&amp;nbsp;클래스&amp;nbsp;개수 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;클래스&amp;nbsp;개수에&amp;nbsp;5를&amp;nbsp;더한&amp;nbsp;이유는&amp;nbsp;해당&amp;nbsp;값&amp;nbsp;만큼의&amp;nbsp;숫자를&amp;nbsp;예측해야함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- tx, ty는 경계상자의 중심 좌표를 계산 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- tw, th는 경계상자의 너비와 높이를 계산 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- c는 객체가 경계 상자 안에 있다고 확신하는 신뢰도 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- p1, p2, ..., pC는 경계상자가 클래스 1, 2, ..., C의 객체를 포함할 확률&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dK5X94/btsNOSU2O2g/pLqbYrk12FwnlmlpKAady0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dK5X94/btsNOSU2O2g/pLqbYrk12FwnlmlpKAady0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dK5X94/btsNOSU2O2g/pLqbYrk12FwnlmlpKAady0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdK5X94%2FbtsNOSU2O2g%2FpLqbYrk12FwnlmlpKAady0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;631&quot; height=&quot;367&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Objectness Score : 바운딩 박스에 객체가 포함되어 있을 확률&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.2 앵커 박스 (Anchor Box)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- YOLOv2에서 도입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사전 정의된 상자(prior box)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체에 가장 근접한 앵커 박스를 맞추고 신경망을 사용해 앵커 박스의 크기를 조정하는 과정 때문에 tx, ty, tw, th이 필요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU8h4t/btsNQxCjqGF/NseyOKl1FtfMMkMcnjT2gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU8h4t/btsNQxCjqGF/NseyOKl1FtfMMkMcnjT2gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU8h4t/btsNQxCjqGF/NseyOKl1FtfMMkMcnjT2gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU8h4t%2FbtsNQxCjqGF%2FNseyOKl1FtfMMkMcnjT2gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;178&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1129&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmIcFD/btsNRNRH6Kr/Z5UbalkhHIl0NRLkKk9GE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmIcFD/btsNRNRH6Kr/Z5UbalkhHIl0NRLkKk9GE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmIcFD/btsNRNRH6Kr/Z5UbalkhHIl0NRLkKk9GE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmIcFD%2FbtsNRNRH6Kr%2FZ5UbalkhHIl0NRLkKk9GE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1129&quot; height=&quot;730&quot; data-origin-width=&quot;1129&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.4 YOLOv8&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&amp;nbsp;&lt;a href=&quot;https://github.com/ultralytics/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/ultralytics/&lt;/a&gt;&lt;br /&gt;*&amp;nbsp;&lt;a href=&quot;https://www.ultralytics.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ultralytics.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1.Yolov8&amp;nbsp;이란? &lt;br /&gt;-&amp;nbsp;YOLOv8은&amp;nbsp;객체&amp;nbsp;탐지(Object&amp;nbsp;Detection),&amp;nbsp;이미지&amp;nbsp;분류(Image&amp;nbsp;Classification),&amp;nbsp;인스턴스&amp;nbsp;분할(Instance&amp;nbsp;Segmentation)&amp;nbsp;작업에&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;최신&amp;nbsp;기술의&amp;nbsp;YOLO&amp;nbsp;모델입니다.&amp;nbsp;YOLOv8은&amp;nbsp;영향력&amp;nbsp;있는&amp;nbsp;YOLOv5&amp;nbsp;모델을&amp;nbsp;개발한&amp;nbsp;[Ultralytics](&lt;a href=&quot;https://ultralytics.com/?ref=blog.roboflow.com)에&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ultralytics.com/?ref=blog.roboflow.com)에&lt;/a&gt;&amp;nbsp;의해&amp;nbsp;개발되었습니다.&amp;nbsp;YOLOv8은&amp;nbsp;YOLOv5와&amp;nbsp;비교하여&amp;nbsp;수많은&amp;nbsp;구조적&amp;nbsp;및&amp;nbsp;개발자&amp;nbsp;경험의&amp;nbsp;변화와&amp;nbsp;개선&amp;nbsp;사항을&amp;nbsp;포함하고&amp;nbsp;있습니다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;YOLOv8은&amp;nbsp;이&amp;nbsp;글을&amp;nbsp;쓰는&amp;nbsp;시점에서&amp;nbsp;Ultralytics가&amp;nbsp;새로운&amp;nbsp;기능을&amp;nbsp;개발하고&amp;nbsp;커뮤니티로부터의&amp;nbsp;피드백에&amp;nbsp;응답하면서&amp;nbsp;활발한&amp;nbsp;개발이&amp;nbsp;진행되고&amp;nbsp;있습니다.&amp;nbsp;실제로&amp;nbsp;Ultralytics가&amp;nbsp;모델을&amp;nbsp;출시하면&amp;nbsp;장기적인&amp;nbsp;지원을&amp;nbsp;받게&amp;nbsp;됩니다.&amp;nbsp;이&amp;nbsp;기관은&amp;nbsp;커뮤니티와&amp;nbsp;협력하여&amp;nbsp;모델을&amp;nbsp;최상의&amp;nbsp;상태로&amp;nbsp;만들기&amp;nbsp;위해&amp;nbsp;노력합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo7Jdi/btsNQ1pnqCl/91vAueBivAKz8wMtOXz9Y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo7Jdi/btsNQ1pnqCl/91vAueBivAKz8wMtOXz9Y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo7Jdi/btsNQ1pnqCl/91vAueBivAKz8wMtOXz9Y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo7Jdi%2FbtsNQ1pnqCl%2F91vAueBivAKz8wMtOXz9Y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;297&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;강력한&amp;nbsp;기초&amp;nbsp;모델과&amp;nbsp;함께&amp;nbsp;YOLOv5&amp;nbsp;관리자들은&amp;nbsp;모델을&amp;nbsp;둘러싼&amp;nbsp;건강한&amp;nbsp;소프트웨어&amp;nbsp;생태계를&amp;nbsp;지원하는&amp;nbsp;데&amp;nbsp;전념했습니다.&amp;nbsp;그들은&amp;nbsp;적극적으로&amp;nbsp;문제를&amp;nbsp;해결하고&amp;nbsp;커뮤니티의&amp;nbsp;요구에&amp;nbsp;따라&amp;nbsp;레포의&amp;nbsp;기능을&amp;nbsp;향상시켰습니다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;지난&amp;nbsp;두&amp;nbsp;해&amp;nbsp;동안,&amp;nbsp;YOLOv5&amp;nbsp;PyTorch&amp;nbsp;레포에서&amp;nbsp;다양한&amp;nbsp;모델들이&amp;nbsp;파생되었으며,&amp;nbsp;[Scaled-YOLOv4](&lt;a href=&quot;https://roboflow.com/model/scaled-yolov4?ref=blog.roboflow.com),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://roboflow.com/model/scaled-yolov4?ref=blog.roboflow.com),&lt;/a&gt;&amp;nbsp;[YOLOR](&lt;a href=&quot;https://blog.roboflow.com/train-yolor-on-a-custom-dataset/),&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.roboflow.com/train-yolor-on-a-custom-dataset/),&lt;/a&gt;&amp;nbsp;[YOLOv7](&lt;a href=&quot;https://blog.roboflow.com/yolov7-breakdown/)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.roboflow.com/yolov7-breakdown/)&lt;/a&gt;&amp;nbsp;등이&amp;nbsp;포함됩니다.&amp;nbsp;[YOLOX](&lt;a href=&quot;https://blog.roboflow.com/how-to-train-yolox-on-a-custom-dataset/)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.roboflow.com/how-to-train-yolox-on-a-custom-dataset/)&lt;/a&gt;&amp;nbsp;및&amp;nbsp;[YOLOv6](&lt;a href=&quot;https://blog.roboflow.com/how-to-train-yolov6-on-a-custom-dataset/)와&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.roboflow.com/how-to-train-yolov6-on-a-custom-dataset/)와&lt;/a&gt;&amp;nbsp;같은&amp;nbsp;다른&amp;nbsp;모델들은&amp;nbsp;각자의&amp;nbsp;PyTorch&amp;nbsp;기반&amp;nbsp;구현에서&amp;nbsp;세계적으로&amp;nbsp;등장했습니다.&amp;nbsp;이&amp;nbsp;과정에서&amp;nbsp;각&amp;nbsp;YOLO&amp;nbsp;모델은&amp;nbsp;모델의&amp;nbsp;정확도와&amp;nbsp;효율성을&amp;nbsp;향상시키는&amp;nbsp;새로운&amp;nbsp;SOTA&amp;nbsp;기술을&amp;nbsp;가져왔습니다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;최근&amp;nbsp;6개월&amp;nbsp;동안,&amp;nbsp;Ultralytics는&amp;nbsp;최신&amp;nbsp;SOTA&amp;nbsp;버전인&amp;nbsp;YOLOv8을&amp;nbsp;연구하는&amp;nbsp;데&amp;nbsp;집중했습니다.&amp;nbsp;YOLOv8은&amp;nbsp;2023년&amp;nbsp;1월&amp;nbsp;10일에&amp;nbsp;출시되었습니다.&amp;nbsp;이&amp;nbsp;모델은&amp;nbsp;이전&amp;nbsp;YOLO&amp;nbsp;버전들의&amp;nbsp;효율성과&amp;nbsp;정확도를&amp;nbsp;향상시킨&amp;nbsp;새로운&amp;nbsp;기술을&amp;nbsp;결합하여&amp;nbsp;더욱&amp;nbsp;강력한&amp;nbsp;객체&amp;nbsp;탐지&amp;nbsp;및&amp;nbsp;인스턴스&amp;nbsp;분할&amp;nbsp;성능을&amp;nbsp;제공합니다.&amp;nbsp;또한,&amp;nbsp;YOLOv8은&amp;nbsp;사용자&amp;nbsp;친화적인&amp;nbsp;API와&amp;nbsp;확장성&amp;nbsp;있는&amp;nbsp;구조를&amp;nbsp;제공하여&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;개발자들이&amp;nbsp;이&amp;nbsp;모델을&amp;nbsp;쉽게&amp;nbsp;적용하고&amp;nbsp;수정할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;되었습니다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;YOLOv8은&amp;nbsp;계속해서&amp;nbsp;발전하고&amp;nbsp;있으며,&amp;nbsp;Ultralytics&amp;nbsp;및&amp;nbsp;커뮤니티는&amp;nbsp;이&amp;nbsp;모델을&amp;nbsp;개선하기&amp;nbsp;위해&amp;nbsp;지속적으로&amp;nbsp;협력하고&amp;nbsp;있습니다.&amp;nbsp;이렇게&amp;nbsp;함으로써&amp;nbsp;YOLO&amp;nbsp;시리즈는&amp;nbsp;앞으로도&amp;nbsp;컴퓨터&amp;nbsp;비전&amp;nbsp;분야에서&amp;nbsp;지속적으로&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;하게&amp;nbsp;될&amp;nbsp;것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YOLOv8 vs YOLOv7 vs YOLOv6 vs YOLOv5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;당장&amp;nbsp;YOLOv8&amp;nbsp;모델은&amp;nbsp;이전&amp;nbsp;YOLO&amp;nbsp;모델에&amp;nbsp;비해&amp;nbsp;훨씬&amp;nbsp;더&amp;nbsp;나은&amp;nbsp;성능을&amp;nbsp;보이는&amp;nbsp;것&amp;nbsp;같습니다.&amp;nbsp;YOLOv5&amp;nbsp;모델뿐만&amp;nbsp;아니라&amp;nbsp;YOLOv8&amp;nbsp;모델도&amp;nbsp;YOLOv7&amp;nbsp;및&amp;nbsp;YOLOv6&amp;nbsp;모델에&amp;nbsp;비해&amp;nbsp;앞서고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmU0rx/btsNRTqQ52c/TpxIYfgWSpIkiOgkXbQRG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmU0rx/btsNRTqQ52c/TpxIYfgWSpIkiOgkXbQRG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmU0rx/btsNRTqQ52c/TpxIYfgWSpIkiOgkXbQRG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmU0rx%2FbtsNRTqQ52c%2FTpxIYfgWSpIkiOgkXbQRG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1196&quot; height=&quot;510&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. SSD (Single Shot MultiBox Detector)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oku0U/btsNRk94Has/Zlh5DgrETRnaIbfpOiSb01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oku0U/btsNRk94Has/Zlh5DgrETRnaIbfpOiSb01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oku0U/btsNRk94Has/Zlh5DgrETRnaIbfpOiSb01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foku0U%2FbtsNRk94Has%2FZlh5DgrETRnaIbfpOiSb01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;832&quot; height=&quot;324&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;SSD는&amp;nbsp;&quot;Single&amp;nbsp;Shot&amp;nbsp;MultiBox&amp;nbsp;Detector&quot;의&amp;nbsp;약자로,&amp;nbsp;객체&amp;nbsp;탐지를&amp;nbsp;위한&amp;nbsp;딥러닝&amp;nbsp;알고리즘입니다.&amp;nbsp;&quot;Single&amp;nbsp;Shot&quot;은&amp;nbsp;객체&amp;nbsp;위치와&amp;nbsp;클래스를&amp;nbsp;단일&amp;nbsp;네트워크&amp;nbsp;통과로&amp;nbsp;예측한다는&amp;nbsp;의미이고,&amp;nbsp;&quot;MultiBox&quot;는&amp;nbsp;다양한&amp;nbsp;크기와&amp;nbsp;비율의&amp;nbsp;기본&amp;nbsp;박스를&amp;nbsp;사용한다는&amp;nbsp;의미입니다. &lt;br /&gt;1.&amp;nbsp;기본&amp;nbsp;네트워크:&amp;nbsp;VGG16이나&amp;nbsp;ResNet과&amp;nbsp;같은&amp;nbsp;사전&amp;nbsp;학습된&amp;nbsp;네트워크를&amp;nbsp;기반으로&amp;nbsp;합니다. &lt;br /&gt;2.&amp;nbsp;다중&amp;nbsp;스케일&amp;nbsp;특징&amp;nbsp;맵:&amp;nbsp;기본&amp;nbsp;네트워크의&amp;nbsp;여러&amp;nbsp;층에서&amp;nbsp;특징&amp;nbsp;맵을&amp;nbsp;추출합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;38&amp;times;38,&amp;nbsp;19&amp;times;19,&amp;nbsp;10&amp;times;10,&amp;nbsp;5&amp;times;5,&amp;nbsp;3&amp;times;3,&amp;nbsp;1&amp;times;1&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;해상도 &lt;br /&gt;3.&amp;nbsp;기본&amp;nbsp;박스(Default&amp;nbsp;Box): &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;특징&amp;nbsp;맵의&amp;nbsp;각&amp;nbsp;위치마다&amp;nbsp;여러&amp;nbsp;개의&amp;nbsp;기본&amp;nbsp;박스&amp;nbsp;설정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;다양한&amp;nbsp;크기와&amp;nbsp;비율(aspect&amp;nbsp;ratio)&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;총&amp;nbsp;약&amp;nbsp;8,000개의&amp;nbsp;기본&amp;nbsp;박스&amp;nbsp;생성 &lt;br /&gt;4.&amp;nbsp;예측&amp;nbsp;값: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;기본&amp;nbsp;박스마다&amp;nbsp;위치&amp;nbsp;오프셋(cx,&amp;nbsp;cy,&amp;nbsp;w,&amp;nbsp;h)&amp;nbsp;예측 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;기본&amp;nbsp;박스마다&amp;nbsp;C+1개&amp;nbsp;클래스(배경&amp;nbsp;포함)&amp;nbsp;신뢰도&amp;nbsp;예측 &lt;br /&gt;5.&amp;nbsp;후처리:&amp;nbsp;임계값&amp;nbsp;이하&amp;nbsp;박스&amp;nbsp;제거&amp;nbsp;및&amp;nbsp;NMS&amp;nbsp;적용 &lt;br /&gt;&lt;br /&gt;=&amp;nbsp;&amp;gt;&amp;nbsp;특징:&amp;nbsp;다양한&amp;nbsp;스케일의&amp;nbsp;특징&amp;nbsp;맵을&amp;nbsp;사용하므로&amp;nbsp;다양한&amp;nbsp;크기의&amp;nbsp;객체를&amp;nbsp;효과적으로&amp;nbsp;탐지할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;YOLO와&amp;nbsp;마찬가지로&amp;nbsp;단일&amp;nbsp;네트워크로&amp;nbsp;실시간&amp;nbsp;처리가&amp;nbsp;가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;4가지 방법의 주요 차이점 비교&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nr9FQ/btsNQPW2ZjK/61CInCyZkw4DFAz4pfMSGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nr9FQ/btsNQPW2ZjK/61CInCyZkw4DFAz4pfMSGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nr9FQ/btsNQPW2ZjK/61CInCyZkw4DFAz4pfMSGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnr9FQ%2FbtsNQPW2ZjK%2F61CInCyZkw4DFAz4pfMSGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;452&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC7M98/btsNQyH0JZN/fu3eOnVKlyxYGt2JHzYQf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC7M98/btsNQyH0JZN/fu3eOnVKlyxYGt2JHzYQf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC7M98/btsNQyH0JZN/fu3eOnVKlyxYGt2JHzYQf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC7M98%2FbtsNQyH0JZN%2Ffu3eOnVKlyxYGt2JHzYQf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;723&quot; height=&quot;294&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Object Detection - Yolov8 [사전학습된 모델 사용하여 예측] &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;Yolo는&amp;nbsp;워싱턴대의&amp;nbsp;Joseph&amp;nbsp;Redmon등이&amp;nbsp;주축이&amp;nbsp;되서&amp;nbsp;만든&amp;nbsp;알고리즘으로&amp;nbsp;Darknet이라는&amp;nbsp;C&amp;nbsp;기반의&amp;nbsp;딥러닝&amp;nbsp;프레임에서&amp;nbsp;만듬&amp;nbsp;(Darknet은&amp;nbsp;Tensorflow와&amp;nbsp;같은&amp;nbsp;딥러닝&amp;nbsp;프레임웍) &lt;br /&gt;-&amp;nbsp;이후&amp;nbsp;Joseph&amp;nbsp;Redmon&amp;nbsp;이&amp;nbsp;더이상&amp;nbsp;computer&amp;nbsp;vision연구를&amp;nbsp;하지&amp;nbsp;않겠다고&amp;nbsp;선언한뒤&amp;nbsp;Yolo의&amp;nbsp;후속&amp;nbsp;버전은&amp;nbsp;계속&amp;nbsp;다른&amp;nbsp;사람들이&amp;nbsp;연구하게&amp;nbsp;됨 &lt;br /&gt;-&amp;nbsp;Yolo&amp;nbsp;v4는&amp;nbsp;이후&amp;nbsp;&amp;nbsp;Alexey&amp;nbsp;Bochkoviskiy가&amp;nbsp;구현했는데,&amp;nbsp;얼마되지&amp;nbsp;않아서&amp;nbsp;glenn&amp;nbsp;jocher가&amp;nbsp;Ultralytics&amp;nbsp;라는&amp;nbsp;개인&amp;nbsp;스타트업을&amp;nbsp;만들고&amp;nbsp;다시&amp;nbsp;Yolo&amp;nbsp;v5를&amp;nbsp;내놓음 &lt;br /&gt;&lt;br /&gt;&amp;lt; 진행 절차 &amp;gt;&lt;br /&gt;1.&amp;nbsp;MS&amp;nbsp;COCO&amp;nbsp;Dataset으로&amp;nbsp;사전학습된&amp;nbsp;Yolov8&amp;nbsp;모델&amp;nbsp;Prediction&amp;nbsp;기능이용&amp;nbsp;시&amp;nbsp;예측에&amp;nbsp;사용할&amp;nbsp;이미지&amp;nbsp;준비 &lt;br /&gt;2.&amp;nbsp;Colab&amp;nbsp;으로&amp;nbsp;데이터셋&amp;nbsp;업로드 &lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;ultralytics&amp;nbsp;패키지&amp;nbsp;설치하기 &lt;br /&gt;-&amp;nbsp;&lt;a href=&quot;https://www.ultralytics.com/ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ultralytics.com/ko&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;&lt;a href=&quot;https://github.com/ultralytics&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/ultralytics&lt;/a&gt;&lt;br /&gt;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pip&amp;nbsp;install&amp;nbsp;ultralytics &lt;br /&gt;``` &lt;br /&gt;4.&amp;nbsp;모델&amp;nbsp;사용하기 &lt;br /&gt;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;from&amp;nbsp;ultralytics&amp;nbsp;import&amp;nbsp;YOLO &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model&amp;nbsp;=&amp;nbsp;YOLO('yolov8n.pt') &lt;br /&gt;```&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;5.&amp;nbsp;예측하기 &lt;br /&gt;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;results&amp;nbsp;=&amp;nbsp;model.predict('test_image.jpg') &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Process&amp;nbsp;results&amp;nbsp;list &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;result&amp;nbsp;in&amp;nbsp;results: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boxes&amp;nbsp;=&amp;nbsp;result.boxes&amp;nbsp;&amp;nbsp;#&amp;nbsp;Boxes&amp;nbsp;object&amp;nbsp;for&amp;nbsp;bounding&amp;nbsp;box&amp;nbsp;outputs &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;masks&amp;nbsp;=&amp;nbsp;result.masks&amp;nbsp;&amp;nbsp;#&amp;nbsp;Masks&amp;nbsp;object&amp;nbsp;for&amp;nbsp;segmentation&amp;nbsp;masks&amp;nbsp;outputs &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keypoints&amp;nbsp;=&amp;nbsp;result.keypoints&amp;nbsp;&amp;nbsp;#&amp;nbsp;Keypoints&amp;nbsp;object&amp;nbsp;for&amp;nbsp;pose&amp;nbsp;outputs &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;probs&amp;nbsp;=&amp;nbsp;result.probs&amp;nbsp;&amp;nbsp;#&amp;nbsp;Probs&amp;nbsp;object&amp;nbsp;for&amp;nbsp;classification&amp;nbsp;outputs &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;obb&amp;nbsp;=&amp;nbsp;result.obb&amp;nbsp;&amp;nbsp;#&amp;nbsp;Oriented&amp;nbsp;boxes&amp;nbsp;object&amp;nbsp;for&amp;nbsp;OBB&amp;nbsp;outputs &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.show()&amp;nbsp;&amp;nbsp;#&amp;nbsp;display&amp;nbsp;to&amp;nbsp;screen &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.save(filename=&quot;result.jpg&quot;)&amp;nbsp;&amp;nbsp;#&amp;nbsp;save&amp;nbsp;to&amp;nbsp;disk&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b89NFN/btsNRTqYh81/rk4pvoP3QU4cshAT2XWkEk/02-11_ObjectDetection_YOLOv8_Basic.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02-11_ObjectDetection_YOLOv8_Basic.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;6.84MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bdpAzV/btsNTODeaN3/ozJYCjZl9aWW2r0TEPXEdK/02-12_ObjectDetection_YOLOv8_CustomData-Roboflow_Windows.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02-12_ObjectDetection_YOLOv8_CustomData-Roboflow_Windows.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.20MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/buZwk4/btsNR7YRP3D/e0Ab6kXHWawBl4aqH29x6K/02-21_FaceDetection_SSD_yolo.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;02-21_FaceDetection_SSD_yolo.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.45MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/499</guid>
      <comments>https://hotari.tistory.com/499#entry499comment</comments>
      <pubDate>Fri, 9 May 2025 12:59:47 +0900</pubDate>
    </item>
    <item>
      <title>1일차</title>
      <link>https://hotari.tistory.com/498</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.08&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Visual Studio Installer&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;699&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7a2e3/btsNN503ixH/a5oU6uTOrBwqOv1wahnGrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7a2e3/btsNN503ixH/a5oU6uTOrBwqOv1wahnGrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7a2e3/btsNN503ixH/a5oU6uTOrBwqOv1wahnGrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7a2e3%2FbtsNN503ixH%2Fa5oU6uTOrBwqOv1wahnGrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1267&quot; height=&quot;699&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;699&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1009&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdA8ja/btsNQp4Jp2C/gNMMCemgin3xyMjCATNtLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdA8ja/btsNQp4Jp2C/gNMMCemgin3xyMjCATNtLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdA8ja/btsNQp4Jp2C/gNMMCemgin3xyMjCATNtLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdA8ja%2FbtsNQp4Jp2C%2FgNMMCemgin3xyMjCATNtLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1009&quot; height=&quot;666&quot; data-origin-width=&quot;1009&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1912&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uODGc/btsNOmVLb1m/k93e0MJgOPzaSZXTmHHB0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uODGc/btsNOmVLb1m/k93e0MJgOPzaSZXTmHHB0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uODGc/btsNOmVLb1m/k93e0MJgOPzaSZXTmHHB0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuODGc%2FbtsNOmVLb1m%2Fk93e0MJgOPzaSZXTmHHB0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1912&quot; height=&quot;1000&quot; data-origin-width=&quot;1912&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스뷰에서 CMFC1View에서 OnDraw 찾기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;1020&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnGQO7/btsNN2J1CKn/i7ykR0F8FbRi2yzsEpb8Q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnGQO7/btsNN2J1CKn/i7ykR0F8FbRi2yzsEpb8Q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnGQO7/btsNN2J1CKn/i7ykR0F8FbRi2yzsEpb8Q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnGQO7%2FbtsNN2J1CKn%2Fi7ykR0F8FbRi2yzsEpb8Q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1184&quot; height=&quot;1020&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;1020&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5lSIk/btsNONTxfzu/aRO8mSjbERGjMBNod2vcd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5lSIk/btsNONTxfzu/aRO8mSjbERGjMBNod2vcd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5lSIk/btsNONTxfzu/aRO8mSjbERGjMBNod2vcd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5lSIk%2FbtsNONTxfzu%2FaRO8mSjbERGjMBNod2vcd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;253&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1421&quot; data-origin-height=&quot;739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFb4K/btsNQvjyi7N/miDPteB7CqLysFzF7k7t20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFb4K/btsNQvjyi7N/miDPteB7CqLysFzF7k7t20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFb4K/btsNQvjyi7N/miDPteB7CqLysFzF7k7t20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFb4K%2FbtsNQvjyi7N%2FmiDPteB7CqLysFzF7k7t20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1421&quot; height=&quot;739&quot; data-origin-width=&quot;1421&quot; data-origin-height=&quot;739&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/burTWW/btsNPdEqASY/TlRvmyskcsgBsAwKKMnXx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/burTWW/btsNPdEqASY/TlRvmyskcsgBsAwKKMnXx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/burTWW/btsNPdEqASY/TlRvmyskcsgBsAwKKMnXx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FburTWW%2FbtsNPdEqASY%2FTlRvmyskcsgBsAwKKMnXx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;248&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1419&quot; data-origin-height=&quot;739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yAnKp/btsNPXVpoWN/dPEfE21u0VeJ7kjkN3JWS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yAnKp/btsNPXVpoWN/dPEfE21u0VeJ7kjkN3JWS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yAnKp/btsNPXVpoWN/dPEfE21u0VeJ7kjkN3JWS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyAnKp%2FbtsNPXVpoWN%2FdPEfE21u0VeJ7kjkN3JWS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1419&quot; height=&quot;739&quot; data-origin-width=&quot;1419&quot; data-origin-height=&quot;739&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CString&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dV0hSA/btsNOhAgmpi/DKocm3kPwzMKqUrlmdroS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dV0hSA/btsNOhAgmpi/DKocm3kPwzMKqUrlmdroS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dV0hSA/btsNOhAgmpi/DKocm3kPwzMKqUrlmdroS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdV0hSA%2FbtsNOhAgmpi%2FDKocm3kPwzMKqUrlmdroS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;312&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cszBq0/btsNPbzS3hb/rLOGsuE9OVqnDQYDOX19r0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cszBq0/btsNPbzS3hb/rLOGsuE9OVqnDQYDOX19r0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cszBq0/btsNPbzS3hb/rLOGsuE9OVqnDQYDOX19r0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcszBq0%2FbtsNPbzS3hb%2FrLOGsuE9OVqnDQYDOX19r0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;332&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mCBct/btsNOpL9RB9/WnO5R4IawGDTLDPmQzSlMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mCBct/btsNOpL9RB9/WnO5R4IawGDTLDPmQzSlMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mCBct/btsNOpL9RB9/WnO5R4IawGDTLDPmQzSlMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmCBct%2FbtsNOpL9RB9%2FWnO5R4IawGDTLDPmQzSlMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;739&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;739&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjDX5V/btsNP40WJVo/czBZta9NSRO3VrXYHX0YW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjDX5V/btsNP40WJVo/czBZta9NSRO3VrXYHX0YW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjDX5V/btsNP40WJVo/czBZta9NSRO3VrXYHX0YW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjDX5V%2FbtsNP40WJVo%2FczBZta9NSRO3VrXYHX0YW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;316&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ct3Y6Z/btsNN9bHjGV/S7bg8IpuGOQtGKVxKWp8nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ct3Y6Z/btsNN9bHjGV/S7bg8IpuGOQtGKVxKWp8nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ct3Y6Z/btsNN9bHjGV/S7bg8IpuGOQtGKVxKWp8nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fct3Y6Z%2FbtsNN9bHjGV%2FS7bg8IpuGOQtGKVxKWp8nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;462&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1MIkk/btsNN3h2jH4/7d5sLyQwuk4ZeEB3VInrA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1MIkk/btsNN3h2jH4/7d5sLyQwuk4ZeEB3VInrA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1MIkk/btsNN3h2jH4/7d5sLyQwuk4ZeEB3VInrA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1MIkk%2FbtsNN3h2jH4%2F7d5sLyQwuk4ZeEB3VInrA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;738&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsrafs/btsNOkwZyhQ/cJs2JpXnbmVM9wFkGLa5fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsrafs/btsNOkwZyhQ/cJs2JpXnbmVM9wFkGLa5fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsrafs/btsNOkwZyhQ/cJs2JpXnbmVM9wFkGLa5fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsrafs%2FbtsNOkwZyhQ%2FcJs2JpXnbmVM9wFkGLa5fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;708&quot; height=&quot;552&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1419&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxOHTg/btsNP6qUOUw/YsyRL6G4rlB9zwxfIDvNH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxOHTg/btsNP6qUOUw/YsyRL6G4rlB9zwxfIDvNH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxOHTg/btsNP6qUOUw/YsyRL6G4rlB9zwxfIDvNH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxOHTg%2FbtsNP6qUOUw%2FYsyRL6G4rlB9zwxfIDvNH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1419&quot; height=&quot;736&quot; data-origin-width=&quot;1419&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;213&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0EmV2/btsNN4uvtcd/NgG1haumw0mQ6R0qVOk3z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0EmV2/btsNN4uvtcd/NgG1haumw0mQ6R0qVOk3z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0EmV2/btsNN4uvtcd/NgG1haumw0mQ6R0qVOk3z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0EmV2%2FbtsNN4uvtcd%2FNgG1haumw0mQ6R0qVOk3z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;213&quot; height=&quot;108&quot; data-origin-width=&quot;213&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnxNxk/btsNOh77HzS/JtjLICJKwseBTnayHr9pD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnxNxk/btsNOh77HzS/JtjLICJKwseBTnayHr9pD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnxNxk/btsNOh77HzS/JtjLICJKwseBTnayHr9pD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnxNxk%2FbtsNOh77HzS%2FJtjLICJKwseBTnayHr9pD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;622&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;실행 결과&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;739&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwiVzk/btsNQox8irI/Pie1Vu0RaVO175QLRHstFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwiVzk/btsNQox8irI/Pie1Vu0RaVO175QLRHstFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwiVzk/btsNQox8irI/Pie1Vu0RaVO175QLRHstFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwiVzk%2FbtsNQox8irI%2FPie1Vu0RaVO175QLRHstFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;739&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;739&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/MFC Application</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/498</guid>
      <comments>https://hotari.tistory.com/498#entry498comment</comments>
      <pubDate>Thu, 8 May 2025 18:27:31 +0900</pubDate>
    </item>
    <item>
      <title>14일차</title>
      <link>https://hotari.tistory.com/497</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.08&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Banana Classification&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/GK4pX/btsNOVCpSG7/IKAWl27Hb2j4In5DpvLTj1/7_10_Banana_Classification.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7_10_Banana_Classification.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.21MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bOm4kC/btsNOq3NsU4/oRZuJErYtreYOQqkw5p0HK/crawling.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;crawling.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.02MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;이진분류 프로젝트&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;정상/폐렴&amp;nbsp;데이터셋&amp;nbsp;사용&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://www.kaggle.com/datasets/paultimothymooney/chest-xray-pneumonia&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.kaggle.com/datasets/paultimothymooney/chest-xray-pneumonia&lt;/a&gt;&lt;br /&gt;2.&amp;nbsp;데이터셋&amp;nbsp;로드하기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;레이블(클래스)&amp;nbsp;리스트&amp;nbsp;선언하여&amp;nbsp;폴더&amp;nbsp;하위&amp;nbsp;이미지&amp;nbsp;읽어&amp;nbsp;입력&amp;nbsp;및&amp;nbsp;출력(X,&amp;nbsp;y)&amp;nbsp;데이터&amp;nbsp;생성 &lt;br /&gt;3.&amp;nbsp;데이터&amp;nbsp;전처리하기 &lt;br /&gt;4.&amp;nbsp;모델&amp;nbsp;구성하기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;CNN&amp;nbsp;모델&amp;nbsp;구성하고&amp;nbsp;Compile&amp;nbsp;하기 &lt;br /&gt;5.&amp;nbsp;모델&amp;nbsp;학습하기 &lt;br /&gt;6.&amp;nbsp;모델&amp;nbsp;학습과정&amp;nbsp;살펴보기(학습횟수에&amp;nbsp;따른&amp;nbsp;accuracy/loss&amp;nbsp;그래프&amp;nbsp;그리기) &lt;br /&gt;7.&amp;nbsp;모델&amp;nbsp;평가&amp;nbsp;및&amp;nbsp;예측하기 &lt;br /&gt;8.&amp;nbsp;모델&amp;nbsp;예측&amp;nbsp;결과&amp;nbsp;출력(이미지+결과)하기&amp;nbsp;(&amp;nbsp;pred_label&amp;nbsp;/&amp;nbsp;true_label&amp;nbsp;) &lt;br /&gt;9.&amp;nbsp;모델&amp;nbsp;저장하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폐렴이란?&lt;br /&gt;폐렴은 주로 폐포라고 알려진 작은 공기주머니에 영향을 미치는 폐의 염증성 질환입니다.증상에는 일반적으로 마른 기침, 가슴 통증, 발열 및 호흡곤란 등이 있습니다. 증상의 심각도는 다양합니다. 폐렴은 보통 바이러스나 박테리아에 감염되어 발생하며, 다른 미생물, 특정 약물, 자가면역질환 등으로 발병하는 경우는 적습니다. 위험인자로는 낭포성 섬유증, 만성폐쇄성폐질환(COPD), 천식, 당뇨병, 심부전, 흡연 이력, 뇌졸중 발생, 면역력 약화 등이 있습니다. 폐렴 진단은 증상 발생과 신체검사를 기반으로 이루어 집니다. 흉부 엑스레이, 혈액 검사, 가래 배양 등이 진단을 확인하는 데 도움이 될 수 있습니다. 이 질병은 지역사회, 병원, 의료 관련 등 발병 장소에 따라 분류할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폐렴 데이터 세트에 대한 설명&lt;br /&gt;데이터 세트는 3개의 폴더(train, test, val)로 구성되며 각 이미지 범주(Pneumonia/Normal)에 대한 하위 폴더를 포함합니다. 5,863개의 X-Ray 이미지(JPEG)와 2개의 카테고리(Pneumonia/Normal)가 있습니다. 흉부 X선 영상(전후방)은 소아 환자 소급 집단에서 선택되었습니다. 모든 흉부 X선 영상 촬영은 환자의 일상적인 임상 치료의 일부로 수행되었습니다. 흉부 X선 영상의 분석을 위해, 흉부 X선 사진은 품질 관리를 위해 품질이 낮거나 읽을 수 없는 이미지는 모두 제거하고 선별하였습니다. AI 시스템을 훈련시키기 전에 두 명의 전무 의사가 이미지에 대한 라벨 분류 작업을 진행하였습니다. 오류를 방지하기 위해 세 번째 전문가가 평가 세트도 확인했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dwHMyP/btsNOWg4Yav/fvTTVyFjXiT5ipKhJCSX5K/7-12_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8_Prj1_%EC%9D%B4%EC%A7%84%EB%B6%84%EB%A5%98_%ED%8F%90%EB%A0%B4%EB%B6%84%EB%A5%98_1.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7-12_신경망모델_Prj1_이진분류_폐렴분류_1.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;3.12MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감정 분류 (Emotion Classification)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;keras의 이미지 증강 방식 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Datasets 로드하고 확인하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.kaggle.com/datasets/msambare/fer2013&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.kaggle.com/datasets/msambare/fer2013&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/1q1sl/btsNOLmv6tf/YYJGP8x7OVKpGMdbW4SAH0/7-13_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8_Prj2_%EB%8B%A4%EC%A4%91%EB%B6%84%EB%A5%98_%EA%B0%90%EC%A0%95%EB%B6%84%EB%A5%98_windows.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7-13_신경망모델_Prj2_다중분류_감정분류_windows.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.41MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 을 사용한 이진/다중 분류 프로젝트 가이드 &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;lt; 다중분류 프로젝트 &amp;gt; &lt;br /&gt;&amp;gt;&amp;nbsp;1.&amp;nbsp;정상/폐렴/Covid-19&amp;nbsp;데이터셋 &lt;br /&gt;&amp;gt;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://www.kaggle.com/datasets/pranavraikokte/covid19-image-dataset/data&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.kaggle.com/datasets/pranavraikokte/covid19-image-dataset/data&lt;/a&gt;&lt;br /&gt;&amp;gt;&amp;nbsp;2.&amp;nbsp;데이터셋&amp;nbsp;준비하기 &lt;br /&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;텐서플로우&amp;nbsp;ImageDataGenerator&amp;nbsp;사용 &lt;br /&gt;&amp;gt;&amp;nbsp;3.&amp;nbsp;데이터&amp;nbsp;전처리하기 &lt;br /&gt;&amp;gt;&amp;nbsp;4.&amp;nbsp;Pretrained-model&amp;nbsp;모델(VGG19&amp;nbsp;or&amp;nbsp;Xception&amp;nbsp;or&amp;nbsp;MobileNetV2&amp;nbsp;등&amp;nbsp;)&amp;nbsp;로드하기&amp;nbsp; &lt;br /&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;새로운&amp;nbsp;분류층&amp;nbsp;추가하기 &lt;br /&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Compile&amp;nbsp;하기 &lt;br /&gt;&amp;gt;&amp;nbsp;5.&amp;nbsp;모델&amp;nbsp;학습하기 &lt;br /&gt;&amp;gt;&amp;nbsp;6.&amp;nbsp;모델&amp;nbsp;학습과정&amp;nbsp;살펴보기&amp;nbsp;(학습횟수에&amp;nbsp;따른&amp;nbsp;accuracy/loss&amp;nbsp;그래프&amp;nbsp;그리기)&amp;nbsp; &lt;br /&gt;&amp;gt;&amp;nbsp;7.&amp;nbsp;모델&amp;nbsp;평가&amp;nbsp;및&amp;nbsp;예측하기 &lt;br /&gt;&amp;gt;&amp;nbsp;8.&amp;nbsp;모델&amp;nbsp;예측&amp;nbsp;결과&amp;nbsp;출력(이미지+결과)하기&amp;nbsp;(&amp;nbsp;pred_label&amp;nbsp;/&amp;nbsp;true_label&amp;nbsp;) &lt;br /&gt;&amp;gt;&amp;nbsp;9.&amp;nbsp;모델&amp;nbsp;저장하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cXdnrl/btsNQea3X6D/nLwOT22DeUdak405nURGqk/COVID_PROJECT.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;COVID_PROJECT.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.34MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/497</guid>
      <comments>https://hotari.tistory.com/497#entry497comment</comments>
      <pubDate>Thu, 8 May 2025 12:57:42 +0900</pubDate>
    </item>
    <item>
      <title>13일차</title>
      <link>https://hotari.tistory.com/496</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.05.07&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차선감지&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/u8jzA/btsNLmH5jU2/odoFWzEvOzRKnkCfWGsfyK/cv_8_lane_detection_pipeline.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;cv_8_lane_detection_pipeline.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/y8WJb/btsNMTSfzId/28jmjfkydWKLTCQiAFkL2K/cv_8_lane_detector.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;cv_8_lane_detector.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1403&quot; data-end=&quot;1421&quot; data-ke-size=&quot;size26&quot;&gt;1. JdOpencvLaneDetect 클래스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1031&quot; data-start=&quot;957&quot;&gt;&lt;b&gt;curr_steering_angle&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1031&quot; data-start=&quot;989&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1031&quot; data-start=&quot;989&quot;&gt;프레임 간 &amp;ldquo;이전 조향각&amp;rdquo;을 저장합니다. 기본값은 90&amp;deg; (직진).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1169&quot; data-start=&quot;1032&quot;&gt;&lt;b&gt;get_lane(frame)&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1169&quot; data-start=&quot;1060&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1096&quot; data-start=&quot;1060&quot;&gt;원본 프레임을 윈도우에 띄우고 (show_image)&lt;/li&gt;
&lt;li data-end=&quot;1169&quot; data-start=&quot;1099&quot;&gt;detect_lane로부터 검출된 차선 좌표(lane_lines)와 차선만 그린 이미지(frame)를 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1396&quot; data-start=&quot;1170&quot;&gt;&lt;b&gt;get_steering_angle&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1396&quot; data-start=&quot;1201&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1230&quot; data-start=&quot;1201&quot;&gt;차선을 못 찾으면 (0, None) 반환&lt;/li&gt;
&lt;li data-end=&quot;1279&quot; data-start=&quot;1233&quot;&gt;compute_steering_angle &amp;rarr; new_angle 계산&lt;/li&gt;
&lt;li data-end=&quot;1353&quot; data-start=&quot;1282&quot;&gt;stabilize_steering_angle로 급격한 변화 제한 &amp;rarr; curr_steering_angle 업데이트&lt;/li&gt;
&lt;li data-end=&quot;1396&quot; data-start=&quot;1356&quot;&gt;최종 조향각 시각화 (display_heading_line)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;1421&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size26&quot;&gt;2. 프레임 처리 파이프라인&lt;/h2&gt;
&lt;h3 data-end=&quot;1459&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size23&quot;&gt;2.1 엣지 검출: detect_edges(frame)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1880&quot; data-start=&quot;1824&quot;&gt;&lt;b&gt;BGR &amp;rarr; HSV 변환&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1880&quot; data-start=&quot;1849&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1880&quot; data-start=&quot;1849&quot;&gt;HSV 공간에서 &amp;lsquo;색상(H)&amp;rsquo; 필터링이 쉽기 때문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2001&quot; data-start=&quot;1881&quot;&gt;&lt;b&gt;두 구간의 적색 마스크&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2001&quot; data-start=&quot;1906&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1952&quot; data-start=&quot;1906&quot;&gt;[0&amp;ndash;40] 구간 + [160&amp;ndash;180] 구간을 합쳐 빨간색 계열 포괄&lt;/li&gt;
&lt;li data-end=&quot;2001&quot; data-start=&quot;1956&quot;&gt;S, V 채널은 [50&amp;ndash;255]로 충분히 밝고 선명한 빨간색만 잡음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2090&quot; data-start=&quot;2002&quot;&gt;&lt;b&gt;Canny 엣지 검출&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2090&quot; data-start=&quot;2026&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2058&quot; data-start=&quot;2026&quot;&gt;1차 threshold = 200, 2차 = 400&lt;/li&gt;
&lt;li data-end=&quot;2090&quot; data-start=&quot;2062&quot;&gt;작은 노이즈는 무시하고, 강한 경계선만 검출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1423&quot; data-end=&quot;1459&quot; data-ke-size=&quot;size23&quot;&gt;2.2 관심 영역 마스킹 : region_of_interest(canny)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2462&quot; data-start=&quot;2409&quot;&gt;&lt;b&gt;왜 하단 절반?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2462&quot; data-start=&quot;2428&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2462&quot; data-start=&quot;2428&quot;&gt;카메라가 앞쪽 도로만 보도록, 하늘&amp;middot;차량 전면부는 제외&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2529&quot; data-start=&quot;2463&quot;&gt;&lt;b&gt;fillPoly + bitwise_and&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2529&quot; data-start=&quot;2500&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2529&quot; data-start=&quot;2500&quot;&gt;마스크 영역만 살리고 나머지는 0(검정) 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1459&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size23&quot;&gt;2.3 허프 선분 검출 : detect_line_segments(cropped_edges)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2846&quot; data-start=&quot;2806&quot;&gt;&lt;b&gt;rho, angle&lt;/b&gt;: 그리드 정밀도(1px, 1&amp;deg;)&lt;/li&gt;
&lt;li data-end=&quot;2896&quot; data-start=&quot;2847&quot;&gt;&lt;b&gt;min_votes&lt;/b&gt;: 직선으로 간주하려면 최소 10개의 뷰(교차점) 필요&lt;/li&gt;
&lt;li data-end=&quot;2969&quot; data-start=&quot;2897&quot;&gt;&lt;b&gt;minLineLength/maxLineGap&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2969&quot; data-start=&quot;2936&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2969&quot; data-start=&quot;2936&quot;&gt;짧은 선분을 버리고, Gap 4px 이하 이으면 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1423&quot; data-end=&quot;1459&quot; data-ke-size=&quot;size23&quot;&gt;2.4 선분 평균화 : average_slope_intercept(frame, line_segments)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 기울기&amp;middot;절편 계산&lt;/p&gt;
&lt;pre id=&quot;code_1746578256641&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fit = np.polyfit((x1, x2), (y1, y2), 1)  
slope, intercept = fit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;좌/우 차선 분류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3293&quot; data-start=&quot;3173&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3212&quot; data-start=&quot;3173&quot;&gt;slope&amp;lt;0 &amp;amp; 화면 왼쪽 2/3에 있을 때 &amp;rarr; 좌측 후보&lt;/li&gt;
&lt;li data-end=&quot;3256&quot; data-start=&quot;3216&quot;&gt;slope&amp;gt;0 &amp;amp; 화면 오른쪽 1/3에 있을 때 &amp;rarr; 우측 후보&lt;/li&gt;
&lt;li data-end=&quot;3293&quot; data-start=&quot;3260&quot;&gt;|slope|&amp;gt;0.75 로 너무 완만한 선분 버림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 평균화 &amp;amp; 좌표 변환&lt;/p&gt;
&lt;pre id=&quot;code_1746578308782&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;avg = np.average(fits, axis=0)  # [slope, intercept]
[[x1, y1, x2, y2]] = make_points(frame, avg)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3483&quot; data-start=&quot;3442&quot;&gt;make_points는 y1=바닥, y2=중간 높이로 고정한 뒤&lt;/li&gt;
&lt;li data-end=&quot;3538&quot; data-start=&quot;3487&quot;&gt;x = (y &amp;minus; intercept) / slope 로 계산, 프레임 밖 좌표는 클램핑&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1459&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size23&quot;&gt;2.5 조향 각도 계산 : compute_steering_angle&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3881&quot; data-start=&quot;3842&quot;&gt;&lt;b&gt;단일 차선&lt;/b&gt;: 선분 끝점(x2) 기준으로 얼마나 벗어났는지&lt;/li&gt;
&lt;li data-end=&quot;3924&quot; data-start=&quot;3882&quot;&gt;&lt;b&gt;이중 차선&lt;/b&gt;: 좌&amp;middot;우 차선 끝점 평균과 화면 중앙(mid) 차이&lt;/li&gt;
&lt;li data-end=&quot;3975&quot; data-start=&quot;3925&quot;&gt;&lt;b&gt;+90&lt;/b&gt;: 90&amp;deg;가 &amp;ldquo;직진&amp;rdquo; 기준, &amp;lt;90&amp;deg;는 좌회전, &amp;gt;90&amp;deg;는 우회전&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1423&quot; data-end=&quot;1459&quot; data-ke-size=&quot;size23&quot;&gt;2.6 각도 안정화 : stabilize_steering_angle&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4246&quot; data-start=&quot;4209&quot;&gt;두 차선 모두 검출되면 &amp;plusmn;5&amp;deg;까지, 한 차선이면 &amp;plusmn;1&amp;deg; 허용&lt;/li&gt;
&lt;li data-end=&quot;4261&quot; data-start=&quot;4247&quot;&gt;급격한 휠 턴 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;4280&quot; data-start=&quot;4268&quot; data-ke-size=&quot;size26&quot;&gt;3. 시각화 유틸&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4427&quot; data-start=&quot;4282&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4341&quot; data-start=&quot;4282&quot;&gt;&lt;b&gt;display_lines&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4341&quot; data-start=&quot;4308&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4341&quot; data-start=&quot;4308&quot;&gt;빈 이미지에 녹색 차선 그린 뒤 원본과 &amp;alpha;-blend&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4427&quot; data-start=&quot;4342&quot;&gt;&lt;b&gt;display_heading_line&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4427&quot; data-start=&quot;4375&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4427&quot; data-start=&quot;4375&quot;&gt;빨간색 화살표 : 화면 하단 중앙 &amp;rarr; 화면 중간 높이, steering angle 방향&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;4449&quot; data-start=&quot;4434&quot; data-ke-size=&quot;size26&quot;&gt;4. 나머지 헬퍼 함수&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4744&quot; data-start=&quot;4451&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4490&quot; data-start=&quot;4451&quot;&gt;&lt;b&gt;length_of_line_segment&lt;/b&gt;: 피타고라스&lt;/li&gt;
&lt;li data-end=&quot;4628&quot; data-start=&quot;4491&quot;&gt;&lt;b&gt;show_image(title, frame, show)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4628&quot; data-start=&quot;4535&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4572&quot; data-start=&quot;4535&quot;&gt;show 플래그가 True일 때만 cv2.imshow&lt;/li&gt;
&lt;li data-end=&quot;4628&quot; data-start=&quot;4575&quot;&gt;&lt;b&gt;주의&lt;/b&gt;: cv2.waitKey(1)가 밖에서 반드시 호출되어야 창이 갱신됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4744&quot; data-start=&quot;4629&quot;&gt;&lt;b&gt;make_points&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4744&quot; data-start=&quot;4654&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4700&quot; data-start=&quot;4654&quot;&gt;(slope, intercept) &amp;rarr; (x1,y1),(x2,y2) 좌표 생성&lt;/li&gt;
&lt;li data-end=&quot;4744&quot; data-start=&quot;4703&quot;&gt;프레임 밖 좌표는 [-width, 2*width] 범위로 클램핑&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;4760&quot; data-start=&quot;4751&quot; data-ke-size=&quot;size23&quot;&gt;핵심 정리&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;4869&quot; data-start=&quot;4762&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;4816&quot; data-start=&quot;4762&quot;&gt;&lt;b&gt;색상 필터&lt;/b&gt; &amp;rarr; &lt;b&gt;엣지 검출&lt;/b&gt; &amp;rarr; &lt;b&gt;ROI 마스크&lt;/b&gt; &amp;rarr; &lt;b&gt;허프 변환&lt;/b&gt; &amp;rarr;&lt;/li&gt;
&lt;li data-end=&quot;4869&quot; data-start=&quot;4817&quot;&gt;&lt;b&gt;선분 분류&amp;middot;평균화&lt;/b&gt; &amp;rarr; &lt;b&gt;조향각 계산&lt;/b&gt; &amp;rarr; &lt;b&gt;각도 안정화&lt;/b&gt; &amp;rarr; &lt;b&gt;시각화&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;5038&quot; data-start=&quot;4871&quot; data-ke-size=&quot;size16&quot;&gt;이 파이프라인 하나하나가 자율주행의 &amp;lsquo;차선 인식 &amp;rarr; 차선 유지&amp;rsquo; 로직을 구현합니다.&lt;br /&gt;각 함수의 파라미터(HSV 임계치, Canny threshold, Hough 파라미터, 안정화 임계)를 튜닝해 주행 환경(조명, 도로 색상)에 맞춰 조절하면 훨씬 견고한 시스템을 만들 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;5038&quot; data-start=&quot;4871&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1746579113130&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#   자율주행 라인 감지 주요 함수 정리 (OpenCV 중심)

---

##   1. `detect_edges(frame)`

```python
def detect_edges(frame):
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    lower_red = np.array([0, 70, 50])
    upper_red = np.array([10, 255, 255])
    mask1 = cv2.inRange(hsv, lower_red, upper_red)

    lower_red2 = np.array([170, 70, 50])
    upper_red2 = np.array([180, 255, 255])
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)

    red_mask = mask1 | mask2
    edges = cv2.Canny(red_mask, 200, 400)

    return edges
```

-   **역할**: 빨간색 차선의 에지(윤곽선) 검출  
-   **사용 함수**:
  - `cv2.cvtColor`: HSV 색 변환
  - `cv2.inRange`: 빨간색 마스크 추출
  - `cv2.Canny`: 에지 검출

---

##   2. `region_of_interest(canny)`

```python
def region_of_interest(canny):
    height, width = canny.shape
    mask = np.zeros_like(canny)
    polygon = np.array([[(0, height), (width, height), (width, height // 2), (0, height // 2)]], np.int32)
    cv2.fillPoly(mask, polygon, 255)
    cropped_edges = cv2.bitwise_and(canny, mask)
    return cropped_edges
```

-   **역할**: 화면 하단 절반만 관심 영역으로 설정  
-   **사용 함수**:
  - `cv2.fillPoly`: 마스크 생성
  - `cv2.bitwise_and`: ROI 외 제거

---

##   3. `detect_line_segments(cropped_edges)`

```python
def detect_line_segments(cropped_edges):
    return cv2.HoughLinesP(cropped_edges, 1, np.pi / 180, 10, np.array([]), minLineLength=8, maxLineGap=4)
```

-   **역할**: 차선으로 추정되는 직선 구간 검출  
-   **사용 함수**:
  - `cv2.HoughLinesP`: 확률적 허프 변환

---

##   4. `average_slope_intercept(frame, line_segments)`

```python
def average_slope_intercept(frame, line_segments):
    height, width, _ = frame.shape
    left_fit = []
    right_fit = []

    for segment in line_segments:
        x1, y1, x2, y2 = segment[0]
        if x1 == x2:
            continue
        slope = (y2 - y1) / (x2 - x1)
        intercept = y1 - slope * x1

        if slope &amp;lt; 0:
            left_fit.append((slope, intercept))
        else:
            right_fit.append((slope, intercept))

    lane_lines = []
    if left_fit:
        left_fit_avg = np.average(left_fit, axis=0)
        lane_lines.append(make_points(frame, left_fit_avg))
    if right_fit:
        right_fit_avg = np.average(right_fit, axis=0)
        lane_lines.append(make_points(frame, right_fit_avg))

    return lane_lines
```

-   **역할**: 좌/우 차선 평균화 및 대표 선 생성  
-   **관련 함수**: `make_points`

---

##   5. `make_points(frame, line)`

```python
def make_points(frame, line):
    height, width, _ = frame.shape
    slope, intercept = line
    y1 = height
    y2 = int(y1 * 0.5)
    x1 = int((y1 - intercept) / slope)
    x2 = int((y2 - intercept) / slope)
    return [[x1, y1, x2, y2]]
```

-   **역할**: 평균화된 직선 정보 &amp;rarr; 이미지상의 점 좌표 변환

---

##   6. `display_lines(frame, lines)`

```python
def display_lines(frame, lines, line_color=(0, 255, 0), line_width=6):
    line_image = np.zeros_like(frame)
    if lines is not None:
        for line in lines:
            x1, y1, x2, y2 = line[0]
            cv2.line(line_image, (x1, y1), (x2, y2), line_color, line_width)
    return cv2.addWeighted(frame, 0.8, line_image, 1, 1)
```

-   **역할**: 검출된 차선을 원본 영상에 시각화  
-   **사용 함수**:
  - `cv2.line`: 선 그리기
  - `cv2.addWeighted`: 원본과 선 이미지 합성

---

##   7. `compute_steering_angle(frame, lane_lines)`

```python
def compute_steering_angle(frame, lane_lines):
    height, width, _ = frame.shape
    if len(lane_lines) == 1:
        x1, _, x2, _ = lane_lines[0][0]
        x_offset = x2 - x1
    elif len(lane_lines) == 2:
        _, _, left_x2, _ = lane_lines[0][0]
        _, _, right_x2, _ = lane_lines[1][0]
        mid = width // 2
        x_offset = (left_x2 + right_x2) // 2 - mid
    else:
        x_offset = 0

    y_offset = height // 2
    angle_to_mid_radian = math.atan(x_offset / y_offset)
    angle_to_mid_deg = int(angle_to_mid_radian * 180.0 / math.pi)
    return angle_to_mid_deg + 90
```

-   **역할**: 현재 차선 기준 조향 각도 계산

---

##   8. `display_heading_line(frame, steering_angle)`

```python
def display_heading_line(frame, steering_angle, line_color=(0, 0, 255), line_width=5):
    heading_image = np.zeros_like(frame)
    height, width, _ = frame.shape
    steering_angle_radian = steering_angle / 180.0 * math.pi
    x1 = width // 2
    y1 = height
    x2 = int(x1 - height / 2 / math.tan(steering_angle_radian))
    y2 = int(height / 2)
    cv2.line(heading_image, (x1, y1), (x2, y2), line_color, line_width)
    return cv2.addWeighted(frame, 0.8, heading_image, 1, 1)
```

-   **역할**: 현재 조향 방향을 시각적으로 표현  
-   **사용 함수**: `cv2.line`, `cv2.addWeighted`

---

##   9. `stabilize_steering_angle(...)`

```python
def stabilize_steering_angle(curr_angle, new_angle, lines_count, max_deviation=5):
    max_deviation *= lines_count
    angle_diff = new_angle - curr_angle

    if abs(angle_diff) &amp;gt; max_deviation:
        stabilized_angle = int(curr_angle + max_deviation * angle_diff / abs(angle_diff))
    else:
        stabilized_angle = new_angle

    return stabilized_angle
```

-   **역할**: 조향각 급변 방지, 안정적인 주행 유지&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 CNN인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지를 1D 벡터 입력으로 평면화하면 2D 이미지의 공간적 특징이 손실됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xMAA8/btsNLoeRDVw/idaKcY6yzwxRfKArEjTz51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xMAA8/btsNLoeRDVw/idaKcY6yzwxRfKArEjTz51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xMAA8/btsNLoeRDVw/idaKcY6yzwxRfKArEjTz51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxMAA8%2FbtsNLoeRDVw%2FidaKcY6yzwxRfKArEjTz51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1038&quot; height=&quot;506&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/05o4t/btsNMd4TCiJ/tk1EDcL9kd1sKfWenbt3tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/05o4t/btsNMd4TCiJ/tk1EDcL9kd1sKfWenbt3tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/05o4t/btsNMd4TCiJ/tk1EDcL9kd1sKfWenbt3tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F05o4t%2FbtsNMd4TCiJ%2Ftk1EDcL9kd1sKfWenbt3tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;845&quot; height=&quot;575&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN (Convolution Neural Network, 합성곱신경망)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CNN 구조&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qIRnp/btsNMQgZbzN/gSjHnQqxyEX7dkJIx5YXL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qIRnp/btsNMQgZbzN/gSjHnQqxyEX7dkJIx5YXL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qIRnp/btsNMQgZbzN/gSjHnQqxyEX7dkJIx5YXL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqIRnp%2FbtsNMQgZbzN%2FgSjHnQqxyEX7dkJIx5YXL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1087&quot; height=&quot;446&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 개요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Input Image : 이미지를 하나의 입력으로 취함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Convolution Layers : Feature Extraction을 수행하는 Layer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Convolution Layer + ReLU : Feature 추출, 의미 없는 특징을 zero화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Pooling Layer : Feature 개수 축소, 중요한 Feature만 유지 (선택적 작업)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Fully-Connected Layer : 비선형 조합 학습 및 분류 작업 수행하는 Layer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Output Class : 작업의 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/23AWs/btsNLZFHHaO/CdUfHVQ4qFfmabIxzHRrnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/23AWs/btsNLZFHHaO/CdUfHVQ4qFfmabIxzHRrnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/23AWs/btsNLZFHHaO/CdUfHVQ4qFfmabIxzHRrnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F23AWs%2FbtsNLZFHHaO%2FCdUfHVQ4qFfmabIxzHRrnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;225&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 활용분야&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 분류 (Classification)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 지역화 (Localization)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지 세분화 (Image Segmentation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 물체 감지 (Object Detection)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuSK9x/btsNMdKxH7N/A0ZFETgAbFsbKa1Ak0OLW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuSK9x/btsNMdKxH7N/A0ZFETgAbFsbKa1Ak0OLW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuSK9x/btsNMdKxH7N/A0ZFETgAbFsbKa1Ak0OLW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuSK9x%2FbtsNMdKxH7N%2FA0ZFETgAbFsbKa1Ak0OLW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1097&quot; height=&quot;321&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해 - 필터 커널 (Filter Kernel)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Filter (Convolution Kernel Matrix)를 적용하여 입력에 대해 특정 성분에 대해서만 뽑아내는 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 예) 사선 정보, 직선 정보, 동그란 정보, 각진 정보, ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 알고 싶은 특정 성분에 따라 Filter의 모양이 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - CNN은 Filter를 갱신하면서 학습하는 것임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Image에 특정 Filter를 Convolution한 결과를 Feature Map이라고 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Feature Map은 Image에 적용된 Filter 개수 만큼의 Channel을 갖게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - n개의 Filter가 적용된 경우 n개 Channel&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Stride : Filter를 순회하는 간격, Stride가 2로 설정되면 2칸씩 이동하면서 convolution하게 됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bepCSO/btsNMxB40hX/TRJDQ3u8LBL0iqjnrp4721/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bepCSO/btsNMxB40hX/TRJDQ3u8LBL0iqjnrp4721/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bepCSO/btsNMxB40hX/TRJDQ3u8LBL0iqjnrp4721/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbepCSO%2FbtsNMxB40hX%2FTRJDQ3u8LBL0iqjnrp4721%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;889&quot; height=&quot;231&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://setosa.io/ev/image-kernels/&quot;&gt;Image Kernels explained visually&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z63ix/btsNLqXWGPV/4X6hX7ko881pfvU0Kkf531/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z63ix/btsNLqXWGPV/4X6hX7ko881pfvU0Kkf531/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z63ix/btsNLqXWGPV/4X6hX7ko881pfvU0Kkf531/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz63ix%2FbtsNLqXWGPV%2F4X6hX7ko881pfvU0Kkf531%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;452&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFFhRD/btsNMeilI31/Lq45cG9Z7Qs2WfTRxKhUy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFFhRD/btsNMeilI31/Lq45cG9Z7Qs2WfTRxKhUy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFFhRD/btsNMeilI31/Lq45cG9Z7Qs2WfTRxKhUy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFFhRD%2FbtsNMeilI31%2FLq45cG9Z7Qs2WfTRxKhUy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;863&quot; height=&quot;533&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 원본 이미지에 특수한 행렬로 컨볼루션을 취함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 행렬의 특성에 따라 원본 이미지로부터 특성이 강조된 이미지를 얻을 수 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkimtx/btsNMQBkrdn/u5inKIrhN4t30LuDAEjNv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkimtx/btsNMQBkrdn/u5inKIrhN4t30LuDAEjNv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkimtx/btsNMQBkrdn/u5inKIrhN4t30LuDAEjNv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkimtx%2FbtsNMQBkrdn%2Fu5inKIrhN4t30LuDAEjNv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1122&quot; height=&quot;484&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BqVEz/btsNLCjMGIS/crXV8z5f6OfCYhqG2KgIFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BqVEz/btsNLCjMGIS/crXV8z5f6OfCYhqG2KgIFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BqVEz/btsNLCjMGIS/crXV8z5f6OfCYhqG2KgIFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBqVEz%2FbtsNLCjMGIS%2FcrXV8z5f6OfCYhqG2KgIFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1040&quot; height=&quot;528&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cs231n.github.io/convolutional-networks/&quot;&gt;https://cs231n.github.io/convolutional-networks/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ojobf/btsNM8BP0ot/LrXeCHvp0doMgvYwgzeDK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ojobf/btsNM8BP0ot/LrXeCHvp0doMgvYwgzeDK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ojobf/btsNM8BP0ot/LrXeCHvp0doMgvYwgzeDK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fojobf%2FbtsNM8BP0ot%2FLrXeCHvp0doMgvYwgzeDK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1030&quot; height=&quot;542&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ufB0P/btsNLCRy2IW/MBnYQxBXqkbiYAKp92S1k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ufB0P/btsNLCRy2IW/MBnYQxBXqkbiYAKp92S1k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ufB0P/btsNLCRy2IW/MBnYQxBXqkbiYAKp92S1k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FufB0P%2FbtsNLCRy2IW%2FMBnYQxBXqkbiYAKp92S1k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;571&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biJOdf/btsNMAS2A8e/BhkwzXaau6DK4WjdsPoB31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biJOdf/btsNMAS2A8e/BhkwzXaau6DK4WjdsPoB31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biJOdf/btsNMAS2A8e/BhkwzXaau6DK4WjdsPoB31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiJOdf%2FbtsNMAS2A8e%2FBhkwzXaau6DK4WjdsPoB31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;569&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cV0hQd/btsNNBw17HN/Hd2kO6PxEAvcsZZwCsi3L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cV0hQd/btsNNBw17HN/Hd2kO6PxEAvcsZZwCsi3L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cV0hQd/btsNNBw17HN/Hd2kO6PxEAvcsZZwCsi3L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV0hQd%2FbtsNNBw17HN%2FHd2kO6PxEAvcsZZwCsi3L0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1103&quot; height=&quot;466&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;543&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V7Vdf/btsNKX9MyVB/9bv3iudASsqA3K9Pu9FBG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V7Vdf/btsNKX9MyVB/9bv3iudASsqA3K9Pu9FBG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V7Vdf/btsNKX9MyVB/9bv3iudASsqA3K9Pu9FBG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV7Vdf%2FbtsNKX9MyVB%2F9bv3iudASsqA3K9Pu9FBG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;958&quot; height=&quot;543&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;543&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 신경망의 높은 계층이 낮은 게층의 출력에 기반한 가중치가 적용된 합으로 형성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 각 높은 계층의 뉴런은 낮은 계층의 특징들을 받아 이들의 가중합을 계산하고 이를 바탕으로 더 복잡한 특징을 인식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Transfer Learning : 이미 대규모 데이터셋에서 사전 훈련된 모델의 지식을 새로운 문제에 적용하는 방법론으로 이때 낮은 계층의 일반적인 특징은 유지되고 높은 계층의 특징은 새로운 문제에 맞게 조정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Capsule Network : 개별 뉴런 대신 &quot;켑슐&quot;이라 불리는 뉴런의 그룹을 사용하여 이미지 내 객체의 다양한 속성과 공간적인 관계를 보다 효과적으로 인식하는 신경망 구조&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xtS6E/btsNK2pGsM2/ppdrVKQgn19wnomp3tpbTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xtS6E/btsNK2pGsM2/ppdrVKQgn19wnomp3tpbTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xtS6E/btsNK2pGsM2/ppdrVKQgn19wnomp3tpbTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxtS6E%2FbtsNK2pGsM2%2FppdrVKQgn19wnomp3tpbTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;268&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해 - Padding&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Convolution Layer에서 Filter를 사용하여 Feature Map을 생성할 때, 이미지 크기가 작아지는 것을 막기 위해 테두리에 Filter 크기를 고려하여 특정 값(일반적으로 0)으로 채우는 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 5x5 이미지에서 3x3 Filter를 사용하면 3x3 크기의 Feature Map이 만들어짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 즉, 5x5 이미지의 둘레에 0을 채워 7x7의 이미지로 만들어서 3x3 Filter를 적용해 5x5의 Feature Map을 얻음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Padding 작업을 통해 인공신경망 이미지 외곽을 인식하도록 하는 효과도 있음 (필수 작업은 아님)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n1fMr/btsNKWiO4M9/x6KIEVqemEcLnCxX4wkbbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n1fMr/btsNKWiO4M9/x6KIEVqemEcLnCxX4wkbbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n1fMr/btsNKWiO4M9/x6KIEVqemEcLnCxX4wkbbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn1fMr%2FbtsNKWiO4M9%2Fx6KIEVqemEcLnCxX4wkbbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;958&quot; height=&quot;284&quot; data-origin-width=&quot;958&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해 - Pooling&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Convolution Layer의 Output을 Input으로 받아 Feature Map의 크기를 줄이거나 특정 데이터를 강조하는 용도로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Max Pooling, Min Pooling, Average Pooling 등의 종류가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Pooling Size를 Stride로 지정하며 이 크기에 따라 줄어드는 양이 줄어듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 입력 데이터의 행, 열 크기는 Pooling 사이즈의 배수(나누어 떨어지는 수)이어야 함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekqHVE/btsNKt2bHfC/zActrMUmyG7dSRgv6uJotK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekqHVE/btsNKt2bHfC/zActrMUmyG7dSRgv6uJotK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekqHVE/btsNKt2bHfC/zActrMUmyG7dSRgv6uJotK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekqHVE%2FbtsNKt2bHfC%2FzActrMUmyG7dSRgv6uJotK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;899&quot; height=&quot;287&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해 - Filter &amp;amp; Pooling&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brfdr3/btsNL0kro51/C9Se8fKNLye8kphyKNQVlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brfdr3/btsNL0kro51/C9Se8fKNLye8kphyKNQVlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brfdr3/btsNL0kro51/C9Se8fKNLye8kphyKNQVlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrfdr3%2FbtsNL0kro51%2FC9Se8fKNLye8kphyKNQVlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1163&quot; height=&quot;375&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN 이해 - Fully Connected Layer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Flatten Layer : CNN의 데이터를 Fully Connected Neural Network의 형태로 변경하는 Layer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 입력 데이터의 Shape 변경만 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 입력 Shape이 (8, 8, 10)이면 Flatten이 적용된 Shape은 (640, 1)이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Softmax Layer : Flatten Layer의 출력을 입력으로 사요하며 분류 클래스에 매칭시키는 Layer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 분류 작업을 실행해 결과를 얻게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 입력 Shape이 (640, 1)이고 분류 클래스가 10인 경우 Softmax가 적용된 출력 Shape은 (10, 1)이 됨. 이때 weight의 shape은 (10, 640)이며 Softmax Layer의 parameter가 6,400개임&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ooNfQ/btsNNzzGprA/Kk0hakWpRwA4HhektdgN4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ooNfQ/btsNNzzGprA/Kk0hakWpRwA4HhektdgN4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ooNfQ/btsNNzzGprA/Kk0hakWpRwA4HhektdgN4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FooNfQ%2FbtsNNzzGprA%2FKk0hakWpRwA4HhektdgN4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;303&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 CNN 네트워크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHm8tm/btsNMcyHV0Y/ZhFdjGuaUJMclwk9K4VPi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHm8tm/btsNMcyHV0Y/ZhFdjGuaUJMclwk9K4VPi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHm8tm/btsNMcyHV0Y/ZhFdjGuaUJMclwk9K4VPi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHm8tm%2FbtsNMcyHV0Y%2FZhFdjGuaUJMclwk9K4VPi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1112&quot; height=&quot;582&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전이학습의 필요성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 딥러닝 모델 학습의 계산 자원과 시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - MNIST 흑백 이미지 인식 모델 &amp;rarr; 최소 3개의 convolution layer + 1개의 fully connected layer 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - CPU 환경에 따라 수 분~수십 분 소요됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - CIFAR-10 고해상도 컬러 이미지 &amp;rarr; 최소 5개의 convolution layer + 2개의 fully connected layer 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 일반 CPU에서 수 시간~수십 시간 소요됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 최신 대규모 CNN 아키텍쳐(ResNet-152, EfficientNet-B7 등) &amp;rarr; 수백 GPU 시간 + 대량의 데이터 필요함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전이학습의 해결책&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Pre-trained CNN 모델 활용 &amp;rarr; 분석 데이터에 맞게 Fine-tuning&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 학습 시간 획기적 단축됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 데이터 부족 상황에서도 우수한 성능 확보 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작 원리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다른 도메인 간의 전이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 동물 사진으로 학습한 모델 &amp;rarr; 자동차/오토바이 분류에 활용 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 도메인 간 거리가 멀수록 효과는 감소함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - Fine-tuning 통해 우수한 성능 확보 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 딥러닝 모델의 층별 특성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 초기 층 &amp;rarr; &quot;일번적인(general)&quot; 특징 추출함 (에지, 색상, 텍스처 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 마지막 층 &amp;rarr; &quot;구체적인(specific)&quot; 특징 추출함 (얼굴 특징, 특정 객체 부분 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 시각적 특징 추출 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 초기 층 &amp;rarr; 수평선, 수직선, 에지, 단순 텍스처 감지함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 중간 층 &amp;rarr; 복잡한 패턴, 질감, 단순 형태 감지함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 마지막 층 &amp;rarr; 고수준 특징 (얼굴, 바퀴, 눈 등) 식별함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 재사용 가능성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 초기 층 &amp;rarr; 다른 데이터셋에도 재사용 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 마지막 층 &amp;rarr; 새로운 문제마다 새로 학습 필요함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**기계학습-신경망(CNN) 알아보기** &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;TensorFlow에서&amp;nbsp;사용하는&amp;nbsp;CNN&amp;nbsp;메서드&amp;nbsp;탐구하기 &lt;br /&gt;2.&amp;nbsp;데이터셋,&amp;nbsp;데이터&amp;nbsp;정규화,&amp;nbsp;모델,&amp;nbsp;loss,&amp;nbsp;accuracy의&amp;nbsp;개념을&amp;nbsp;정리하기 &lt;br /&gt;3.&amp;nbsp;VGGNet&amp;nbsp;그림을&amp;nbsp;보고&amp;nbsp;직접&amp;nbsp;만들어보기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**[CNN&amp;nbsp;기반의&amp;nbsp;숫자&amp;nbsp;이미지&amp;nbsp;분류&amp;nbsp;-&amp;nbsp;MNIST&amp;nbsp;데이터셋&amp;nbsp;활용_by&amp;nbsp;Tensorflow]**&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.라이브러리&amp;nbsp;가져오기&lt;/p&gt;
&lt;pre id=&quot;code_1746596189359&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# tensorflow 불러오기
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.데이터셋&amp;nbsp;로드&amp;nbsp;및&amp;nbsp;전처리하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;MNIST는&amp;nbsp;0부터&amp;nbsp;9까지&amp;nbsp;숫자&amp;nbsp;손글씨로&amp;nbsp;이루어진&amp;nbsp;데이터셋으로\ &lt;br /&gt;28X28사이즈의&amp;nbsp;60000의&amp;nbsp;훈련&amp;nbsp;데이터와&amp;nbsp;10000개의&amp;nbsp;테스트&amp;nbsp;데이터로&amp;nbsp;구성되어&amp;nbsp;있습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;x_train.shape&amp;nbsp;==&amp;nbsp;(60000,&amp;nbsp;28,&amp;nbsp;28)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;x_test.shape&amp;nbsp;==&amp;nbsp;(10000,&amp;nbsp;28,&amp;nbsp;28)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;y_train.shape&amp;nbsp;==&amp;nbsp;(60000,)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;y_test.shape&amp;nbsp;==&amp;nbsp;(10000,)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKL9in/btsNMzmNMAn/HWiMs03Q2yJVnHqvGNnYhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKL9in/btsNMzmNMAn/HWiMs03Q2yJVnHqvGNnYhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKL9in/btsNMzmNMAn/HWiMs03Q2yJVnHqvGNnYhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKL9in%2FbtsNMzmNMAn%2FHWiMs03Q2yJVnHqvGNnYhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;560&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Convolution&amp;nbsp;Neural&amp;nbsp;Network를&amp;nbsp;구성하고&amp;nbsp;있는&amp;nbsp;매개변수(Arguments)는&amp;nbsp;filters부터&amp;nbsp;bias_contraint까지&amp;nbsp;총&amp;nbsp;16개로&amp;nbsp;구성되어&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;**filters**&amp;nbsp;:&amp;nbsp;출력되는&amp;nbsp;결과의&amp;nbsp;차원수를&amp;nbsp;의미합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;filter가 영향을 준 부분은 Tuple의 마지막 부분인 channel파트입니다. 즉&amp;nbsp;filter를&amp;nbsp;몇개&amp;nbsp;주는지에&amp;nbsp;따라서&amp;nbsp;channel수가&amp;nbsp;바뀌게&amp;nbsp;되고&amp;nbsp;이는&amp;nbsp;차원수가&amp;nbsp;바뀌는&amp;nbsp;것을&amp;nbsp;의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;**kernel_size**&amp;nbsp;:&amp;nbsp;kernel_size가&amp;nbsp;위에&amp;nbsp;있는&amp;nbsp;코드는&amp;nbsp;3,&amp;nbsp;아래에&amp;nbsp;있는&amp;nbsp;코드는&amp;nbsp;2로&amp;nbsp;되어&amp;nbsp;있습니다.&amp;nbsp;그래서&amp;nbsp;output이&amp;nbsp;바뀐&amp;nbsp;파트는&amp;nbsp;Tuple의&amp;nbsp;2번째,&amp;nbsp;3번째에&amp;nbsp;영향을&amp;nbsp;줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cE0IZg/btsNMgOBCce/2LET3YNLyRs6qPGKugpY90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cE0IZg/btsNMgOBCce/2LET3YNLyRs6qPGKugpY90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cE0IZg/btsNMgOBCce/2LET3YNLyRs6qPGKugpY90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcE0IZg%2FbtsNMgOBCce%2F2LET3YNLyRs6qPGKugpY90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;344&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에&amp;nbsp;있는&amp;nbsp;gif를&amp;nbsp;보게&amp;nbsp;되면&amp;nbsp;빨간색&amp;nbsp;6x6&amp;nbsp;이미지를&amp;nbsp;3x3&amp;nbsp;filter를&amp;nbsp;이용해&amp;nbsp;convolution&amp;nbsp;연산이&amp;nbsp;진행되고&amp;nbsp;결과값은&amp;nbsp;보라색&amp;nbsp;이미지인&amp;nbsp;4x4이미지입니다. &lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;방식을&amp;nbsp;수학적으로&amp;nbsp;표현하면&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;표현가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;output&amp;nbsp;=&amp;nbsp;input&amp;nbsp;-&amp;nbsp;filter&amp;nbsp;+&amp;nbsp;1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;**strides**\&amp;nbsp;:&amp;nbsp;strides는&amp;nbsp;filter&amp;nbsp;이동을&amp;nbsp;1개씩&amp;nbsp;가는&amp;nbsp;것이&amp;nbsp;아니라&amp;nbsp;n개씩&amp;nbsp;가도록&amp;nbsp;설정하는&amp;nbsp;매개변수입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ofABQ/btsNNdjhVTC/wpTQ7LRmKCP1ndjwowgtBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ofABQ/btsNNdjhVTC/wpTQ7LRmKCP1ndjwowgtBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ofABQ/btsNNdjhVTC/wpTQ7LRmKCP1ndjwowgtBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FofABQ%2FbtsNNdjhVTC%2FwpTQ7LRmKCP1ndjwowgtBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;285&quot; height=&quot;283&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에&amp;nbsp;있는&amp;nbsp;그림을&amp;nbsp;보게&amp;nbsp;되면&amp;nbsp;5x5&amp;nbsp;이미지를&amp;nbsp;3x3&amp;nbsp;filter가&amp;nbsp;2개씩&amp;nbsp;가도록&amp;nbsp;설정되어&amp;nbsp;있습니다.\ &lt;br /&gt;해당&amp;nbsp;설정을&amp;nbsp;하지&amp;nbsp;않았다면&amp;nbsp;output의&amp;nbsp;크기는&amp;nbsp;3x3이&amp;nbsp;되어야&amp;nbsp;하지만&amp;nbsp;stride가&amp;nbsp;설정되면서&amp;nbsp;2x2로&amp;nbsp;출력값이&amp;nbsp;나오게&amp;nbsp;되었습니다.&amp;nbsp;해당&amp;nbsp;내용도&amp;nbsp;코드로도&amp;nbsp;확인해보도록&amp;nbsp;하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stride가 적용되면 실제 output의 크기는 step만큼 나누어져서 계산됩니다.&lt;br /&gt;그렇기에&amp;nbsp;stride가&amp;nbsp;적용된&amp;nbsp;output_shape은&amp;nbsp;다음과&amp;nbsp;같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;64&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3zYsz/btsNMBEYwjh/lGF8h0tmcgfkffAASEuzK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3zYsz/btsNMBEYwjh/lGF8h0tmcgfkffAASEuzK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3zYsz/btsNMBEYwjh/lGF8h0tmcgfkffAASEuzK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3zYsz%2FbtsNMBEYwjh%2FlGF8h0tmcgfkffAASEuzK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;64&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;64&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;**padding** &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;padding을&amp;nbsp;하는&amp;nbsp;이유는&amp;nbsp;filter는&amp;nbsp;가운데&amp;nbsp;파트는&amp;nbsp;몇번씩&amp;nbsp;거치면서&amp;nbsp;계산되지만&amp;nbsp;끝에&amp;nbsp;있는&amp;nbsp;edge부분은&amp;nbsp;한번밖에&amp;nbsp;계산되지&amp;nbsp;않습니다.&amp;nbsp;그렇기에&amp;nbsp;padding을&amp;nbsp;주어서&amp;nbsp;edge를&amp;nbsp;잘&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;하는&amp;nbsp;장치입니다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;TensorFlow의&amp;nbsp;경우&amp;nbsp;padding은&amp;nbsp;'자동'으로&amp;nbsp;적용하며&amp;nbsp;'valid'는&amp;nbsp;적용하지&amp;nbsp;않은&amp;nbsp;것이며&amp;nbsp;'same'은&amp;nbsp;padding이&amp;nbsp;적용된&amp;nbsp;상황입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;padding이&amp;nbsp;적용되었을&amp;nbsp;때&amp;nbsp;Output&amp;nbsp;shape은&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;계산됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ch6lek/btsNNjKAGZ0/SLvcLRSyxIb4p9a8YdfkLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ch6lek/btsNNjKAGZ0/SLvcLRSyxIb4p9a8YdfkLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ch6lek/btsNNjKAGZ0/SLvcLRSyxIb4p9a8YdfkLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fch6lek%2FbtsNNjKAGZ0%2FSLvcLRSyxIb4p9a8YdfkLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;62&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;**input_shape**&amp;nbsp;:&amp;nbsp;처음&amp;nbsp;layer를&amp;nbsp;쌓을&amp;nbsp;떄&amp;nbsp;설정해주는&amp;nbsp;값이며 &lt;br /&gt;-&amp;nbsp;**activation**&amp;nbsp;:&amp;nbsp;convolution&amp;nbsp;연산&amp;nbsp;이후&amp;nbsp;활성화함수를&amp;nbsp;고르는&amp;nbsp;매개변수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;신경망&amp;nbsp;모델을&amp;nbsp;만들려면&amp;nbsp;모델의&amp;nbsp;층을&amp;nbsp;구성한&amp;nbsp;다음&amp;nbsp;모델을&amp;nbsp;컴파일합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1746596664811&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from tensorflow import keras

# 모델 아키텍처 정의
model = keras.Sequential([
    # 입력 레이어 정의
    keras.layers.Input(shape=(28, 28, 1)),
    # 첫 번째 Convolution layer를 정의
    keras.layers.Conv2D(16, (3, 3), activation='relu'),
    # 두 번째MaxPooling2D layer 추가 (pooling size: (2, 2))
    keras.layers.MaxPooling2D(pool_size=(2, 2)),

    # 두 번째 Convolution layer 추가 (output 차원수: 32, filter 사이즈: 3, 활성화 함수: relu)
    keras.layers.Conv2D(32, (3, 3), padding='same', activation='relu'),
    # 두 번째 MaxPooling2D layer 추가
    keras.layers.MaxPooling2D(pool_size=(2, 2)),

    # 차원을 줄이는 Flatten layer 추가
    keras.layers.Flatten(),

    # Dense layer 추가 (output unit: 32, 활성화 함수: relu)
    keras.layers.Dense(32, activation='relu'),

    # 최종 Dense layer 추가 (output unit: 10, 활성화 함수: softmax)
    keras.layers.Dense(10, activation='softmax')
])

# 모델 확인
model.summary()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzcEjc/btsNMSGtAw6/PU1OxKgzM6bTl9lhVv4dZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzcEjc/btsNMSGtAw6/PU1OxKgzM6bTl9lhVv4dZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzcEjc/btsNMSGtAw6/PU1OxKgzM6bTl9lhVv4dZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzcEjc%2FbtsNMSGtAw6%2FPU1OxKgzM6bTl9lhVv4dZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;481&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1746596728547&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모델 컴파일. 손실 함수, 옵티마이저, 메트릭 정의
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
              
# 훈련 데이터를 이용해 모델 학습
model.fit(train_images, train_labels, epochs=5)

# 테스트 데이터로 모델 평가. 손실과 정확도 출력
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('테스트 loss:', test_loss, '테스트 정확도:', test_acc)

# 예측 결과 시각화
predictions = model.predict(test_images)
num_rows = 3
num_cols = 3
num_images = num_rows * num_cols
plt.figure(figsize=(2*num_cols, 2*num_rows))
for i in range(num_images):
    plt.subplot(num_rows, num_cols, i+1)
    plt.imshow(test_images[i], cmap=plt.cm.binary)
    plt.xticks([])
    plt.yticks([])
    predicted_label = np.argmax(predictions[i])
    true_label = test_labels[i]
    if predicted_label == true_label:
        color = 'green'
    else:
        color = 'red'
    plt.xlabel(&quot;{} ({})&quot;.format(predicted_label, true_label), color=color)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tOmkK/btsNL0rGUjy/nD2uRS1ETmGBFmZmdZWDi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tOmkK/btsNL0rGUjy/nD2uRS1ETmGBFmZmdZWDi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tOmkK/btsNL0rGUjy/nD2uRS1ETmGBFmZmdZWDi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtOmkK%2FbtsNL0rGUjy%2FnD2uRS1ETmGBFmZmdZWDi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;497&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bNc7Yc/btsNL1EapPs/4K5YvB6xg5TKm6s5w5pd6K/7-11_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8_CNN%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0_%EB%B6%84%EB%A5%98%28%EC%9D%B4%EB%AF%B8%EC%A7%80%29_%EC%86%90%EA%B8%80%EC%94%A8%EC%88%AB%EC%9E%90%EB%B6%84%EB%A5%98_Tensorflow.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7-11_신경망모델_CNN알아보기_분류(이미지)_손글씨숫자분류_Tensorflow.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.95MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 데이터 수집&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/czF2y1/btsNNCDduG5/vy4BQI1X5aCAi5F7HKWCxk/7_10_Image_Downloader.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7_10_Image_Downloader.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b3zOM9/btsNL1YD8bN/cY9RVABUEzbVZKmtiIyhO0/7_10_Banana_Classification.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;7_10_Banana_Classification.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.16MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/496</guid>
      <comments>https://hotari.tistory.com/496#entry496comment</comments>
      <pubDate>Wed, 7 May 2025 16:49:20 +0900</pubDate>
    </item>
    <item>
      <title>12일차</title>
      <link>https://hotari.tistory.com/495</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.04.29&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 변형 - 흐림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흐림 효과 (Blur)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;블러링(Blurring)&amp;nbsp;또는&amp;nbsp;스무딩(Smoothing)이라&amp;nbsp;불림 &lt;br /&gt;- 영상이나 이미지를 번지게 하며, 해당 픽셀의 주변 값들과 비교하고 계산해서 픽셀들의 색상을 재조정함&lt;br /&gt;- 단순히 이미지를 흐리게 만드는 것뿐만 아니라 노이즈를 제거해서 연산 시 계산을 빠르고 정확하게 수행하는 데 도움을 줌&lt;br /&gt;-&amp;nbsp;노이즈를&amp;nbsp;줄이거나&amp;nbsp;외부&amp;nbsp;영향을&amp;nbsp;최소화하는&amp;nbsp;데&amp;nbsp;사용 &lt;br /&gt;- 의도적으로 이미지를 흐리게 하는 이유는 보이는 정보를 조정함으로써 외곽선 정보를 보다 단순하게 처리함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w7HkP/btsNCpMh1Sv/4nHunCMTWnNq4KbYJnobA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w7HkP/btsNCpMh1Sv/4nHunCMTWnNq4KbYJnobA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w7HkP/btsNCpMh1Sv/4nHunCMTWnNq4KbYJnobA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw7HkP%2FbtsNCpMh1Sv%2F4nHunCMTWnNq4KbYJnobA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;264&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.blur()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이것은&amp;nbsp;단순&amp;nbsp;평균&amp;nbsp;블러링을&amp;nbsp;수행합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;지정된&amp;nbsp;커널&amp;nbsp;크기&amp;nbsp;내의&amp;nbsp;모든&amp;nbsp;픽셀&amp;nbsp;값의&amp;nbsp;평균을&amp;nbsp;계산하여&amp;nbsp;이미지를&amp;nbsp;흐리게&amp;nbsp;만듭니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 결과적으로 동일한 가중치로 주변 픽셀의 값을 평균화합니다.&lt;br /&gt;`dst&amp;nbsp;=&amp;nbsp;cv2.blur(src,&amp;nbsp;ksize,&amp;nbsp;anchor,&amp;nbsp;borderType)`&amp;nbsp;:입력&amp;nbsp;이미지(src)를&amp;nbsp;커널&amp;nbsp;크기(ksize),&amp;nbsp;고정점(anchor),&amp;nbsp;테두리&amp;nbsp;외삽법(borderType)으로&amp;nbsp;흐림&amp;nbsp;효과를&amp;nbsp;적용한&amp;nbsp;결과&amp;nbsp;이미지(dst)를&amp;nbsp;반환 &lt;br /&gt;-&amp;nbsp;ksize&amp;nbsp;:&amp;nbsp;커널(kernel)&amp;nbsp;크기-이미지에서&amp;nbsp;(x,&amp;nbsp;y)의&amp;nbsp;픽셀과&amp;nbsp;설정한&amp;nbsp;크기의&amp;nbsp;사각형&amp;nbsp;커널이며&amp;nbsp;커널&amp;nbsp;크기가&amp;nbsp;클수록&amp;nbsp;더&amp;nbsp;흐려짐 &lt;br /&gt;-&amp;nbsp;anchor&amp;nbsp;:(-1,&amp;nbsp;-1)&amp;nbsp;커널의&amp;nbsp;중심을&amp;nbsp;의미함,&amp;nbsp;기본값:&amp;nbsp;커널&amp;nbsp;내에서의&amp;nbsp;앵커&amp;nbsp;포인트(커널을&amp;nbsp;이미지에&amp;nbsp;적용할&amp;nbsp;때&amp;nbsp;기준이&amp;nbsp;되는&amp;nbsp;특정&amp;nbsp;픽셀&amp;nbsp;위치) &lt;br /&gt;-&amp;nbsp;borderType&amp;nbsp;:&amp;nbsp;테두리&amp;nbsp;외삽법(Border&amp;nbsp;Extrapolation)&amp;nbsp;-&amp;nbsp;컨벌루션을&amp;nbsp;적용할&amp;nbsp;때,&amp;nbsp;이미지&amp;nbsp;가장자리&amp;nbsp;부분의&amp;nbsp;처리&amp;nbsp;방식 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;borderType=cv2.BORDER_DEFAULT&amp;nbsp;:&amp;nbsp;기본&amp;nbsp;테두리&amp;nbsp;유형&amp;nbsp;사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가우시안 블러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`blurred_image&amp;nbsp;=&amp;nbsp;cv2.GaussianBlur(source_image,&amp;nbsp;(kernel_width,&amp;nbsp;kernel_height),&amp;nbsp;sigmaX,&amp;nbsp;sigmaY)` &lt;br /&gt;-&amp;nbsp;이미지를&amp;nbsp;흐리게&amp;nbsp;하면서도&amp;nbsp;노이즈도&amp;nbsp;제거함.&amp;nbsp;이렇게&amp;nbsp;하면&amp;nbsp;이미지&amp;nbsp;연산할때&amp;nbsp;보다&amp;nbsp;빠르게&amp;nbsp;정확하게&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있음&amp;nbsp;=&amp;nbsp;&amp;gt;&amp;nbsp;노이즈&amp;nbsp;제거,&amp;nbsp;이미지&amp;nbsp;부드럽게&amp;nbsp;처리,&amp;nbsp;엣지&amp;nbsp;검출을&amp;nbsp;위한&amp;nbsp;사전&amp;nbsp;처리&amp;nbsp;단계&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;목적으로&amp;nbsp;활용 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;가우시안&amp;nbsp;함수를&amp;nbsp;기반으로&amp;nbsp;한&amp;nbsp;가중치를&amp;nbsp;사용하여&amp;nbsp;블러링을&amp;nbsp;수행합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;커널의&amp;nbsp;중심에&amp;nbsp;가까운&amp;nbsp;픽셀은&amp;nbsp;더&amp;nbsp;높은&amp;nbsp;가중치를&amp;nbsp;가지며,&amp;nbsp;멀리&amp;nbsp;떨어진&amp;nbsp;픽셀은&amp;nbsp;더&amp;nbsp;낮은&amp;nbsp;가중치를&amp;nbsp;가집니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;커널의&amp;nbsp;크기는&amp;nbsp;블러링의&amp;nbsp;정도를&amp;nbsp;결정&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;큰&amp;nbsp;커널은&amp;nbsp;이미지를&amp;nbsp;더&amp;nbsp;흐리게&amp;nbsp;만들며,&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;작은&amp;nbsp;커널은&amp;nbsp;덜&amp;nbsp;흐리게&amp;nbsp;만듬 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;sigmaX&amp;nbsp;:&amp;nbsp;가우시안&amp;nbsp;블러에서&amp;nbsp;X&amp;nbsp;방향의&amp;nbsp;표준&amp;nbsp;편차는&amp;nbsp;블러의&amp;nbsp;정도와&amp;nbsp;연관이&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;큰&amp;nbsp;표준&amp;nbsp;편차는&amp;nbsp;이미지를&amp;nbsp;더&amp;nbsp;흐리게&amp;nbsp;만들며,&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;작은&amp;nbsp;표준&amp;nbsp;편차는&amp;nbsp;덜&amp;nbsp;흐리게&amp;nbsp;만듬 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;sigmaY :&amp;nbsp;Y&amp;nbsp;방향(세로)&amp;nbsp;가우시안&amp;nbsp;커널&amp;nbsp;표준편차&amp;nbsp;(기본값은&amp;nbsp;0)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.blur() vs cv2.GaussianBlur() vs cv2.medianBlur()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`cv2.blur()`평균블러링링:&amp;nbsp;단순히&amp;nbsp;주변&amp;nbsp;픽셀&amp;nbsp;평균&amp;nbsp;계산-&amp;nbsp;더&amp;nbsp;단순하고&amp;nbsp;빠르게&amp;nbsp;이미지를&amp;nbsp;흐리게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;특정&amp;nbsp;애플리케이션에서는&amp;nbsp;이것이&amp;nbsp;더&amp;nbsp;적합할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;-&amp;nbsp;`cv2.GaussianBlur()`:가중&amp;nbsp;평균&amp;nbsp;(중앙&amp;nbsp;픽셀에&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;가중치)&amp;nbsp;-&amp;nbsp;이미지의&amp;nbsp;노이즈를&amp;nbsp;줄이는&amp;nbsp;데&amp;nbsp;특히&amp;nbsp;효과적입니다.&amp;nbsp;가우시안&amp;nbsp;블러는&amp;nbsp;노이즈&amp;nbsp;제거와&amp;nbsp;동시에&amp;nbsp;이미지의&amp;nbsp;경계를&amp;nbsp;부드럽게&amp;nbsp;만들어&amp;nbsp;주기&amp;nbsp;때문에&amp;nbsp;많은&amp;nbsp;컴퓨터&amp;nbsp;비전&amp;nbsp;작업에서&amp;nbsp;선호됨. &lt;br /&gt;-&amp;nbsp;`cv2.medianBlur()`:&amp;nbsp;미디언&amp;nbsp;블러링&amp;nbsp;(cv2.medianBlur)&amp;nbsp;-&amp;nbsp;주변&amp;nbsp;픽셀의&amp;nbsp;중앙값을&amp;nbsp;사용,&amp;nbsp;노이즈&amp;nbsp;제거에&amp;nbsp;최고(특히&amp;nbsp;소금-후추&amp;nbsp;노이즈&amp;nbsp;제거&amp;nbsp;효과&amp;nbsp;뛰어남)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샤프닝 (Sharpening)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;영상을&amp;nbsp;날카롭게&amp;nbsp;만드는&amp;nbsp;처리 &lt;br /&gt;-&amp;nbsp;영상을&amp;nbsp;선명하게&amp;nbsp;할&amp;nbsp;때&amp;nbsp;사용 &lt;br /&gt;- 중심 화소값과 인접 화소값의 차이를 더 크게 만듬&lt;br /&gt;-&amp;nbsp;cv2.filter2D&amp;nbsp;:&amp;nbsp;OpenCV&amp;nbsp;라이브러리에서&amp;nbsp;제공하는&amp;nbsp;함수로,&amp;nbsp;사용자가&amp;nbsp;정의한&amp;nbsp;커널(또는&amp;nbsp;필터)를&amp;nbsp;이미지에&amp;nbsp;적용하여&amp;nbsp;2차원&amp;nbsp;필터링을&amp;nbsp;수행하는&amp;nbsp;기능을&amp;nbsp;제공 &lt;br /&gt;-&amp;nbsp;`dst&amp;nbsp;=&amp;nbsp;cv2.filter2D(src,&amp;nbsp;ddepth,&amp;nbsp;kernel,&amp;nbsp;anchor,&amp;nbsp;delta,&amp;nbsp;borderType)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;src:&amp;nbsp;입력&amp;nbsp;이미지입니다.&amp;nbsp;보통&amp;nbsp;numpy&amp;nbsp;배열로&amp;nbsp;표현됩니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ddepth:&amp;nbsp;결과&amp;nbsp;이미지의&amp;nbsp;깊이(비트&amp;nbsp;단위)입니다.&amp;nbsp;-1로&amp;nbsp;지정하면&amp;nbsp;입력&amp;nbsp;이미지와&amp;nbsp;동일한&amp;nbsp;깊이를&amp;nbsp;사용합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;kernel:&amp;nbsp;필터링에&amp;nbsp;사용될&amp;nbsp;커널입니다.&amp;nbsp;numpy&amp;nbsp;배열로&amp;nbsp;정의되며,&amp;nbsp;일반적으로&amp;nbsp;부동소수점&amp;nbsp;값으로&amp;nbsp;구성됩니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;anchor:&amp;nbsp;선택적으로&amp;nbsp;커널의&amp;nbsp;중심을&amp;nbsp;지정하는&amp;nbsp;점입니다.&amp;nbsp;기본값은&amp;nbsp;(-1,&amp;nbsp;-1)로,&amp;nbsp;커널의&amp;nbsp;중심을&amp;nbsp;사용합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;delta:&amp;nbsp;필터링된&amp;nbsp;픽셀에&amp;nbsp;추가적으로&amp;nbsp;더해질&amp;nbsp;값.&amp;nbsp;기본값은&amp;nbsp;0입니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- borderType: 이미지 가장자리 픽셀을 확장하는 방식을 결정합니다. 예를 들어, cv2.BORDER_CONSTANT, cv2.BORDER_REFLECT, cv2.- BORDER_WRAP 등이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 검출 (경계선)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Canny Edge Detection &lt;br /&gt;-&amp;nbsp;이미지에서&amp;nbsp;**윤곽선(에지)**를&amp;nbsp;똑똑하게&amp;nbsp;찾아주는&amp;nbsp;아주&amp;nbsp;중요한&amp;nbsp;기법 &lt;br /&gt;-&amp;nbsp;컬러이미지에&amp;nbsp;적용할&amp;nbsp;경우&amp;nbsp;내부적으로&amp;nbsp;회색조로&amp;nbsp;변경한&amp;nbsp;후&amp;nbsp;에지&amp;nbsp;검출을&amp;nbsp;수행함. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;Canny&amp;nbsp;Edge&amp;nbsp;Detection&amp;nbsp;4단계 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;1️⃣&amp;nbsp;Noise&amp;nbsp;Reduction&amp;nbsp;(노이즈&amp;nbsp;제거)&amp;nbsp;:&amp;nbsp;잡음&amp;nbsp;때문에&amp;nbsp;잘못된&amp;nbsp;엣지를&amp;nbsp;검출하는&amp;nbsp;걸&amp;nbsp;막기&amp;nbsp;위해&amp;nbsp;**Gaussian&amp;nbsp;Blur&amp;nbsp;(가우시안&amp;nbsp;블러링)**을&amp;nbsp;적용해서&amp;nbsp;부드럽게&amp;nbsp;만들기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;blur&amp;nbsp;=&amp;nbsp;cv2.GaussianBlur(img,&amp;nbsp;(5,5),&amp;nbsp;1.4) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;``` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2️⃣&amp;nbsp;Finding&amp;nbsp;Intensity&amp;nbsp;Gradient&amp;nbsp;(기울기(gradient)&amp;nbsp;계산)&amp;nbsp;:&amp;nbsp;밝기가&amp;nbsp;얼마나&amp;nbsp;급격하게&amp;nbsp;변하는지&amp;nbsp;(밝기&amp;nbsp;차이)&amp;nbsp;계산.&amp;nbsp;변하는&amp;nbsp;정도(기울기)와&amp;nbsp;방향(어디로&amp;nbsp;밝아지는지)을&amp;nbsp;알아내기&amp;nbsp;위해&amp;nbsp;OpenCV&amp;nbsp;내부에서는&amp;nbsp;Sobel&amp;nbsp;연산&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Gx&amp;nbsp;=&amp;nbsp;Sobel(blur,&amp;nbsp;방향=x)&amp;nbsp;&amp;nbsp;#&amp;nbsp;수평&amp;nbsp;기울기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Gy&amp;nbsp;=&amp;nbsp;Sobel(blur,&amp;nbsp;방향=y)&amp;nbsp;&amp;nbsp;#&amp;nbsp;수직&amp;nbsp;기울기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;magnitude&amp;nbsp;=&amp;nbsp;sqrt(Gx^2&amp;nbsp;+&amp;nbsp;Gy^2)&amp;nbsp;&amp;nbsp;#&amp;nbsp;전체&amp;nbsp;기울기&amp;nbsp;크기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;direction&amp;nbsp;=&amp;nbsp;atan2(Gy,&amp;nbsp;Gx)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;기울기&amp;nbsp;방향 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;``` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;3️⃣&amp;nbsp;Non-Maximum&amp;nbsp;Suppression&amp;nbsp;(비최대&amp;nbsp;억제)&amp;nbsp;:&amp;nbsp;기울기(gradient)가&amp;nbsp;가장&amp;nbsp;강한&amp;nbsp;부분만&amp;nbsp;살리고,&amp;nbsp;주변&amp;nbsp;약한&amp;nbsp;부분은&amp;nbsp;지움&amp;nbsp;=&amp;gt;&amp;nbsp;가장&amp;nbsp;뾰족한(최고점)만&amp;nbsp;남겨서&amp;nbsp;엣지를&amp;nbsp;가늘게&amp;nbsp;만들어주는&amp;nbsp;단계&amp;nbsp;(최대&amp;nbsp;크기의&amp;nbsp;픽셀만&amp;nbsp;골라내서&amp;nbsp;에지&amp;nbsp;픽셀로&amp;nbsp;설정)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blgfPc/btsNCguQvMC/nZKm8G57KIRhKRQK5aKrgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blgfPc/btsNCguQvMC/nZKm8G57KIRhKRQK5aKrgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blgfPc/btsNCguQvMC/nZKm8G57KIRhKRQK5aKrgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblgfPc%2FbtsNCguQvMC%2FnZKm8G57KIRhKRQK5aKrgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;184&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;4️⃣&amp;nbsp;Hysteresis&amp;nbsp;Thresholding&amp;nbsp;(이력&amp;nbsp;기반&amp;nbsp;문턱값&amp;nbsp;처리)&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;에지&amp;nbsp;후보들이&amp;nbsp;실제&amp;nbsp;에지인지&amp;nbsp;아닌지를&amp;nbsp;결정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;조명이나&amp;nbsp;다른&amp;nbsp;변수의&amp;nbsp;영향으로&amp;nbsp;인해&amp;nbsp;영상의&amp;nbsp;그래디언트가&amp;nbsp;미세하게&amp;nbsp;변화할&amp;nbsp;수&amp;nbsp;있기때문에&amp;nbsp;픽셀&amp;nbsp;값이&amp;nbsp;임계점보다&amp;nbsp;커지거나&amp;nbsp;낮아질&amp;nbsp;수&amp;nbsp;있는데,&amp;nbsp;이를&amp;nbsp;방지하기&amp;nbsp;위해&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;임계값을&amp;nbsp;이용함.&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;강한&amp;nbsp;엣지는&amp;nbsp;무조건&amp;nbsp;엣지로&amp;nbsp;채택하고,&amp;nbsp;약한&amp;nbsp;엣지는&amp;nbsp;강한&amp;nbsp;엣지와&amp;nbsp;연결된&amp;nbsp;경우에만&amp;nbsp;엣지로&amp;nbsp;인정&amp;nbsp;=&amp;gt;&amp;nbsp;진짜&amp;nbsp;엣지와&amp;nbsp;연결된&amp;nbsp;부분만&amp;nbsp;살려서&amp;nbsp;깔끔하게&amp;nbsp;정리.&amp;nbsp;OpenCV에서는&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;문턱값을&amp;nbsp;설정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```python &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;edges&amp;nbsp;=&amp;nbsp;cv2.Canny(img,&amp;nbsp;threshold1=50,&amp;nbsp;threshold2=150) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;-&amp;nbsp;`cv2.Canny(img,&amp;nbsp;threshold1,&amp;nbsp;threshold2)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;threshold1&amp;nbsp;(하위&amp;nbsp;임계값,&amp;nbsp;minVal):&amp;nbsp;이&amp;nbsp;값&amp;nbsp;이하의&amp;nbsp;그레이디언트(명암&amp;nbsp;변화율)를&amp;nbsp;가진&amp;nbsp;픽셀은&amp;nbsp;에지가&amp;nbsp;아니라고&amp;nbsp;간주함(에지로&amp;nbsp;간주되기&amp;nbsp;위한&amp;nbsp;최소한의&amp;nbsp;명암&amp;nbsp;변화량) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;threshold2&amp;nbsp;(상위&amp;nbsp;임계값,&amp;nbsp;maxVal):&amp;nbsp;이&amp;nbsp;값&amp;nbsp;이상의&amp;nbsp;그레이디언트를&amp;nbsp;가진&amp;nbsp;픽셀은&amp;nbsp;강한&amp;nbsp;에지로&amp;nbsp;간주되며,&amp;nbsp;threshold1과&amp;nbsp;threshold2&amp;nbsp;사이의&amp;nbsp;그레이디언트를&amp;nbsp;가진&amp;nbsp;픽셀은&amp;nbsp;연결된&amp;nbsp;강한&amp;nbsp;에지가&amp;nbsp;존재할&amp;nbsp;경우에만&amp;nbsp;에지로&amp;nbsp;간주함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 검출 - 윤곽선&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;컨투어(Contour)&amp;nbsp;:&amp;nbsp;경계선을&amp;nbsp;연결한&amp;nbsp;선&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;컨투어(우리말로&amp;nbsp;등고선,&amp;nbsp;윤곽선,&amp;nbsp;외곽선&amp;nbsp;등으로&amp;nbsp;번역)s는&amp;nbsp;지도에서&amp;nbsp;지형의&amp;nbsp;높이가&amp;nbsp;같은&amp;nbsp;영역을&amp;nbsp;하나의&amp;nbsp;선으로&amp;nbsp;표시하는&amp;nbsp;용도로&amp;nbsp;많이&amp;nbsp;사용됨 &lt;br /&gt;- 영상에서는 같은 색상이나 밝기의 연속된 점을 찾아 잇는 곡선을 찾아내면 모양 분석과 객체 인식에 사용할 수 있음&lt;br /&gt;-&amp;nbsp;`contour,&amp;nbsp;hierarchy&amp;nbsp;=&amp;nbsp;cv2.findCountours(src,&amp;nbsp;mode,&amp;nbsp;method[,&amp;nbsp;contours,&amp;nbsp;hierarchy,&amp;nbsp;offset])[-2:]` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;src&amp;nbsp;:&amp;nbsp;입력&amp;nbsp;이미지,&amp;nbsp;바이너리&amp;nbsp;스케일,&amp;nbsp;검은색&amp;nbsp;배경&amp;nbsp;흰색&amp;nbsp;전경 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mode&amp;nbsp;:&amp;nbsp;컨투어&amp;nbsp;제공&amp;nbsp;방식&amp;nbsp;선택 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_EXTERNAL&amp;nbsp;:&amp;nbsp;가장&amp;nbsp;바깥쪽&amp;nbsp;라인만&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_LIST&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;라인을&amp;nbsp;계층&amp;nbsp;없이&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_CCOMP&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;라인을&amp;nbsp;2계층으로&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_TREE&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;라인의&amp;nbsp;모든&amp;nbsp;계층&amp;nbsp;정보를&amp;nbsp;트리&amp;nbsp;구조로&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;method&amp;nbsp;:&amp;nbsp;근사&amp;nbsp;값&amp;nbsp;방식&amp;nbsp;선택 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_NONE&amp;nbsp;:&amp;nbsp;근사&amp;nbsp;계산하지&amp;nbsp;않고&amp;nbsp;모든&amp;nbsp;좌표&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_SIMPLE&amp;nbsp;:&amp;nbsp;컨투어&amp;nbsp;꼭짓점&amp;nbsp;좌표만&amp;nbsp;제공 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_TC89_L1&amp;nbsp;:&amp;nbsp;Teh-Chin&amp;nbsp;알고리즘으로&amp;nbsp;좌표&amp;nbsp;개수&amp;nbsp;축소 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_TC89_KCOS&amp;nbsp;:&amp;nbsp;Teh-Chin&amp;nbsp;알고리즘으로&amp;nbsp;좌표&amp;nbsp;개수&amp;nbsp;축소 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;contours&amp;nbsp;:&amp;nbsp;검출한&amp;nbsp;건투어&amp;nbsp;좌표,&amp;nbsp;파이썬&amp;nbsp;리스트 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- hierarchy : 컨투어 계층 정보&lt;br /&gt;-&amp;nbsp;`cv2.drawContours(img,&amp;nbsp;contours,&amp;nbsp;contourIdx,&amp;nbsp;color,&amp;nbsp;thickness)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img&amp;nbsp;:&amp;nbsp;입력&amp;nbsp;영상 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;contours&amp;nbsp;:&amp;nbsp;그림&amp;nbsp;그릴&amp;nbsp;컨투어&amp;nbsp;배열 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;contourIdx&amp;nbsp;:&amp;nbsp;그림&amp;nbsp;그릴&amp;nbsp;컨투어&amp;nbsp;인덱스,&amp;nbsp;-1&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;컨투어&amp;nbsp;표시 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;color&amp;nbsp;:&amp;nbsp;색상 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;thickness&amp;nbsp;:&amp;nbsp;선&amp;nbsp;두께,&amp;nbsp;0:채우기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 윤곽선 검출 : findContours()&lt;br /&gt;-&amp;nbsp;원본이미지를&amp;nbsp;직접&amp;nbsp;수정하는&amp;nbsp;함수임.&amp;nbsp;따라서&amp;nbsp;원본이미지를&amp;nbsp;보존하기위해&amp;nbsp;복사해서&amp;nbsp;사용 &lt;br /&gt;&lt;br /&gt;3. 윤곽선 그리기 : drawContours()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윤곽선 찾을 때 근사치 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cv2.findContours() : 이진화 이미지에서 윤곽선(컨투어)를 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`contours,&amp;nbsp;hierarchy&amp;nbsp;=&amp;nbsp;cv2.findContours(binary,&amp;nbsp;cv2.RETR_CCOMP,&amp;nbsp;cv2.CHAIN_APPROX_NONE)` &lt;br /&gt;-&amp;nbsp;contours&amp;nbsp;:&amp;nbsp;이미지에서&amp;nbsp;경계를&amp;nbsp;찾고,&amp;nbsp;경계&amp;nbsp;좌표를&amp;nbsp;contours와&amp;nbsp;같은&amp;nbsp;형태로&amp;nbsp;반환합니다. &lt;br /&gt;- 윤곽선, 계층구조 = cv2.findContours(이진화 이미지, 검색 방법, 근사화 방법)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;검색&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_EXTERNAL&amp;nbsp;:&amp;nbsp;외곽&amp;nbsp;윤곽선만&amp;nbsp;검출하며,&amp;nbsp;계층&amp;nbsp;구조를&amp;nbsp;구성하지&amp;nbsp;않습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_LIST&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;윤곽선을&amp;nbsp;검출하며,&amp;nbsp;계층&amp;nbsp;구조를&amp;nbsp;구성하지&amp;nbsp;않습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_CCOMP&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;윤곽선을&amp;nbsp;검출하며,&amp;nbsp;계층&amp;nbsp;구조는&amp;nbsp;2단계로&amp;nbsp;구성합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.RETR_TREE&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;윤곽선을&amp;nbsp;검출하며,&amp;nbsp;계층&amp;nbsp;구조를&amp;nbsp;모두&amp;nbsp;형성합니다.&amp;nbsp;(Tree&amp;nbsp;구조) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;근사화&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_NONE&amp;nbsp;:&amp;nbsp;윤곽점들의&amp;nbsp;모든&amp;nbsp;점을&amp;nbsp;반환합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_SIMPLE&amp;nbsp;:&amp;nbsp;윤곽점들&amp;nbsp;단순화&amp;nbsp;수평,&amp;nbsp;수직&amp;nbsp;및&amp;nbsp;대각선&amp;nbsp;요소를&amp;nbsp;압축하고&amp;nbsp;끝점만&amp;nbsp;남겨&amp;nbsp;둡니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_TC89_L1&amp;nbsp;:&amp;nbsp;프리먼&amp;nbsp;체인&amp;nbsp;코드에서의&amp;nbsp;윤곽선으로&amp;nbsp;적용합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.CHAIN_APPROX_TC89_KCOS&amp;nbsp;:&amp;nbsp;프리먼&amp;nbsp;체인&amp;nbsp;코드에서의&amp;nbsp;윤곽선으로&amp;nbsp;적용합니다.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;contours&amp;nbsp;:&amp;nbsp;Numpy&amp;nbsp;구조의&amp;nbsp;배열로&amp;nbsp;검출된&amp;nbsp;윤곽선의&amp;nbsp;지점들이&amp;nbsp;담겨있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;hierarchy&amp;nbsp;:&amp;nbsp;윤곽선의&amp;nbsp;계층&amp;nbsp;구조를&amp;nbsp;의미.&amp;nbsp;윤곽선의&amp;nbsp;포함&amp;nbsp;관계&amp;nbsp;여부&amp;nbsp;나타냄&amp;nbsp;(외곽/내곽/같은&amp;nbsp;게층구조)윤곽선에&amp;nbsp;해당하는&amp;nbsp;속정&amp;nbsp;정보&amp;nbsp;포함함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윤곽선 찾기 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cv2.RETR_EXTERNAL : 가장 외곽의 윤곽선만 찾음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cv2.RETR_LIST : 모든 윤곽선 찾음 (계층 정보 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cv2.RETR_TREE : 모든 윤곽선 찾음 (계층 정보를 트리 구조로 생성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cv2.drawContours() : 검출된 윤곽선 그리기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]] ) -&amp;gt; image`&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.drawContours(이미지,&amp;nbsp;[윤곽선],&amp;nbsp;윤곽선&amp;nbsp;인덱스,&amp;nbsp;(B,&amp;nbsp;G,&amp;nbsp;R),&amp;nbsp;두께,&amp;nbsp;선형타입) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;image&amp;nbsp;:&amp;nbsp;윤곽선을&amp;nbsp;그릴&amp;nbsp;대상&amp;nbsp;이미지&amp;nbsp;-&amp;nbsp;빈&amp;nbsp;캔버스에&amp;nbsp;그림 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;윤곽선&amp;nbsp;:&amp;nbsp;검출된&amp;nbsp;윤곽선들이&amp;nbsp;저장된&amp;nbsp;Numpy&amp;nbsp;배열(좌표&amp;nbsp;리스트) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 윤곽선 인덱스: 검출된 윤곽선 배열에서 몇 번째 인덱스의 윤곽선을 그릴지를 의미합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;윤곽선&amp;nbsp;인덱스를&amp;nbsp;0으로&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;0&amp;nbsp;번째&amp;nbsp;인덱스의&amp;nbsp;윤곽선을&amp;nbsp;그리게&amp;nbsp;됩니다.&amp;nbsp;하지만,&amp;nbsp;윤곽선&amp;nbsp;인수를&amp;nbsp;대괄호로&amp;nbsp;다시&amp;nbsp;묶을&amp;nbsp;경우,&amp;nbsp;0&amp;nbsp;번째&amp;nbsp;인덱스가&amp;nbsp;최댓값인&amp;nbsp;배열로&amp;nbsp;변경됩니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 동일한 방식으로 [윤곽선], 0과 윤곽선, -1은 동일한 의미를 갖습니다. (-1은 윤곽선 배열 모두를 의미)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 예시 [ 2 -1 1 -1]&amp;nbsp;&amp;nbsp;: [다음 윤곽선, 이전 윤곽선, 내곽 윤곽선, 외곽 윤곽선]에 대한 인덱스 정보를 포함&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;인덱스&amp;nbsp;0의&amp;nbsp;윤곽선의&amp;nbsp;다음&amp;nbsp;윤곽선은&amp;nbsp;인덱스&amp;nbsp;2의&amp;nbsp;윤곽선을&amp;nbsp;의미하며&amp;nbsp;이전&amp;nbsp;윤곽선은&amp;nbsp;존재하지&amp;nbsp;않다는&amp;nbsp;것을&amp;nbsp;의미 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;내곽&amp;nbsp;윤곽선은&amp;nbsp;인덱스&amp;nbsp;1에&amp;nbsp;해당하는&amp;nbsp;윤곽선을&amp;nbsp;자식&amp;nbsp;윤곽선으로&amp;nbsp;두고&amp;nbsp;있다는&amp;nbsp;의미입니다.즉,&amp;nbsp;인덱스&amp;nbsp;0&amp;nbsp;윤곽선&amp;nbsp;내부에&amp;nbsp;인덱스&amp;nbsp;1의&amp;nbsp;윤곽선이&amp;nbsp;포함되어&amp;nbsp;있습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;외곽&amp;nbsp;윤곽선은&amp;nbsp;-1의&amp;nbsp;값을&amp;nbsp;갖고&amp;nbsp;있으므로&amp;nbsp;외곽&amp;nbsp;윤곽선은&amp;nbsp;존재하지&amp;nbsp;않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경계 사각형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 윤곽선의 경계면을 둘러싸는 사각형 : boundingRect()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면적&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 면적 이상의 윤곽선만 찾고 싶을 때 사용 : contourArea()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bi5OfG/btsND0qMIzZ/jdrCKXCVmaqRTME4XtJvEK/41_%EB%B8%94%EB%9F%AC%EB%A7%81.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;41_블러링.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.31MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/c3tnyg/btsNDqwM5Os/SkkLZIHXdnXXFCZBfWhdj0/42_%EC%83%A4%ED%94%84%EB%8B%9D-%EC%BB%A4%EB%84%90%EA%B8%B0%EB%B0%98%ED%95%84%ED%84%B0.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;42_샤프닝-커널기반필터.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.78MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/brLAUT/btsNDx3IHdc/jTWQEYYZq4VVw8Nq5DYKs1/43_%EC%97%90%EC%A7%80%EA%B2%80%EC%B6%9C.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;43_에지검출.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.33MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b2wL9s/btsNCCrbD4y/lfHKBvIBf9ZdLyhXYFarF0/44_%EC%9C%A4%EA%B3%BD%EC%84%A0%EA%B2%80%EC%B6%9C%26amp%3B%EC%99%B8%EA%B3%BD%EC%84%A0%EA%B7%B8%EB%A6%AC%EA%B8%B0.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;44_윤곽선검출&amp;amp;amp;외곽선그리기.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.25MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HOG (Histogram of Oriented Gradient)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;주로&amp;nbsp;**사람&amp;nbsp;인식(Human&amp;nbsp;Detection)**과&amp;nbsp;보행자&amp;nbsp;검출을&amp;nbsp;하기&amp;nbsp;위해&amp;nbsp;널리&amp;nbsp;사용되는&amp;nbsp;기법&amp;nbsp;중&amp;nbsp;하나로&amp;nbsp;이미지의&amp;nbsp;지역적&amp;nbsp;형태(윤곽선,&amp;nbsp;경계)를&amp;nbsp;잡아내는&amp;nbsp;특성(Feature)&amp;nbsp;추출&amp;nbsp;알고리즘 &lt;br /&gt;-&amp;nbsp;그래디언트&amp;nbsp;방향&amp;nbsp;히스토그램을&amp;nbsp;의미하며&amp;nbsp;사람이&amp;nbsp;서&amp;nbsp;있는&amp;nbsp;영상에서&amp;nbsp;그래디언트를&amp;nbsp;구하고,&amp;nbsp;그래디언트의&amp;nbsp;크기와&amp;nbsp;방향&amp;nbsp;성분을&amp;nbsp;이용하여&amp;nbsp;사람이&amp;nbsp;서&amp;nbsp;있는&amp;nbsp;형태에&amp;nbsp;대한&amp;nbsp;특징&amp;nbsp;벡터를&amp;nbsp;정의&amp;nbsp;=&amp;gt;&amp;nbsp;모양(shape)&amp;nbsp;정보에&amp;nbsp;강함,&amp;nbsp;배경&amp;nbsp;노이즈에&amp;nbsp;강인&amp;nbsp;&amp;nbsp; &lt;br /&gt;-&amp;nbsp;이미지를&amp;nbsp;일정한&amp;nbsp;셀로&amp;nbsp;나누고,&amp;nbsp;각&amp;nbsp;셀에서&amp;nbsp;그래디언트&amp;nbsp;방향의&amp;nbsp;히스토그램을&amp;nbsp;계산&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbheJQ/btsNEDPscQG/PxrQXuA5YpeNpKBhZqkjWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbheJQ/btsNEDPscQG/PxrQXuA5YpeNpKBhZqkjWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbheJQ/btsNEDPscQG/PxrQXuA5YpeNpKBhZqkjWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbheJQ%2FbtsNEDPscQG%2FPxrQXuA5YpeNpKBhZqkjWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;263&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;1)대상&amp;nbsp;영역을&amp;nbsp;일정&amp;nbsp;크기의&amp;nbsp;셀로&amp;nbsp;분할 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2)각&amp;nbsp;셀마다&amp;nbsp;edge&amp;nbsp;픽셀(gradient&amp;nbsp;magnitude가&amp;nbsp;일정&amp;nbsp;값&amp;nbsp;이상인&amp;nbsp;픽셀)들의&amp;nbsp;방향에&amp;nbsp;대한&amp;nbsp;히스토그램을&amp;nbsp;구한&amp;nbsp;후&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;3)이들&amp;nbsp;히스토그램&amp;nbsp;bin&amp;nbsp;값들을&amp;nbsp;일렬로&amp;nbsp;연결한&amp;nbsp;벡터&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;템플릿&amp;nbsp;매칭과&amp;nbsp;히스토그램&amp;nbsp;매칭의&amp;nbsp;중간&amp;nbsp;단계에&amp;nbsp;있는&amp;nbsp;매칭&amp;nbsp;방법으로&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있으며&amp;nbsp;블록&amp;nbsp;단위로는&amp;nbsp;기하학적&amp;nbsp;정보를&amp;nbsp;유지하되,&amp;nbsp;각&amp;nbsp;블록&amp;nbsp;내부에서는&amp;nbsp;히스토그램을&amp;nbsp;사용함으로써&amp;nbsp;로컬한&amp;nbsp;변화에는&amp;nbsp;어느정도&amp;nbsp;강인한&amp;nbsp;특성을&amp;nbsp;가짐 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;1)&amp;nbsp;입력영상에서&amp;nbsp;부분영상&amp;nbsp;추출 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2)&amp;nbsp;크기&amp;nbsp;정규화&amp;nbsp;:&amp;nbsp;64X128&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c10H2E/btsNCcsUnQE/7RqsLkIfBo00ZAlK1BV2IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c10H2E/btsNCcsUnQE/7RqsLkIfBo00ZAlK1BV2IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c10H2E/btsNCcsUnQE/7RqsLkIfBo00ZAlK1BV2IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc10H2E%2FbtsNCcsUnQE%2F7RqsLkIfBo00ZAlK1BV2IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;195&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;3)&amp;nbsp;64X128영상의&amp;nbsp;gradient&amp;nbsp;계산하여&amp;nbsp;방향과&amp;nbsp;크기&amp;nbsp;성분&amp;nbsp;파악 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;4)&amp;nbsp;8*8&amp;nbsp;크기의&amp;nbsp;셀분할 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;5)&amp;nbsp;방향&amp;nbsp;시스토그램의&amp;nbsp;bin&amp;nbsp;개수&amp;nbsp;=&amp;nbsp;9&amp;nbsp;=&amp;gt;&amp;nbsp;360도를&amp;nbsp;9개&amp;nbsp;구간으로&amp;nbsp;나옴 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt;&amp;nbsp;8*8&amp;nbsp;셀&amp;nbsp;4개를&amp;nbsp;하나의&amp;nbsp;블록을&amp;nbsp;지정&amp;nbsp;(&amp;nbsp;블록&amp;nbsp;하나의&amp;nbsp;크기는&amp;nbsp;16X16&amp;nbsp;&amp;nbsp;=&amp;gt;&amp;nbsp;각&amp;nbsp;블록의&amp;nbsp;히스토그램&amp;nbsp;빈&amp;nbsp;개수는&amp;nbsp;4X9=36개)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvEMyQ/btsNCg2GWZC/79fWnTkAQtICs9PSfSWBH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvEMyQ/btsNCg2GWZC/79fWnTkAQtICs9PSfSWBH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvEMyQ/btsNCg2GWZC/79fWnTkAQtICs9PSfSWBH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvEMyQ%2FbtsNCg2GWZC%2F79fWnTkAQtICs9PSfSWBH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;271&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`hog(gray,&amp;nbsp;orientations=9,&amp;nbsp;pixels_per_cell=(8,&amp;nbsp;8),&amp;nbsp;cells_per_block=(2,&amp;nbsp;2),&amp;nbsp;visualize=True,&amp;nbsp;block_norm='L2-Hys') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;orientations=9&amp;nbsp;:&amp;nbsp;방향(bin)&amp;nbsp;개수&amp;nbsp;(360도를&amp;nbsp;9등분)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;pixels_per_cell=(8,&amp;nbsp;8)&amp;nbsp;:&amp;nbsp;한&amp;nbsp;셀(cell)&amp;nbsp;크기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cells_per_block=(2,&amp;nbsp;2)&amp;nbsp;:&amp;nbsp;블록(block)&amp;nbsp;내&amp;nbsp;셀&amp;nbsp;개수&amp;nbsp;(정규화&amp;nbsp;단위) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;visualize=True&amp;nbsp;: HOG&amp;nbsp;시각화&amp;nbsp;결과도&amp;nbsp;리턴 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;block_norm='L2-Hys'&amp;nbsp;:블록&amp;nbsp;정규화&amp;nbsp;방법&amp;nbsp;(L2-Hysteresis)&amp;nbsp;=&amp;gt;&amp;nbsp;블록(block)&amp;nbsp;안의&amp;nbsp;HOG&amp;nbsp;히스토그램&amp;nbsp;벡터를 &lt;br /&gt;&quot;너무&amp;nbsp;작거나&amp;nbsp;너무&amp;nbsp;큰&amp;nbsp;값을&amp;nbsp;정리(normalize)해서&amp;nbsp;비교가&amp;nbsp;잘&amp;nbsp;되게&quot;&amp;nbsp;하는&amp;nbsp;과정 &lt;br /&gt;&lt;br /&gt;-`cv2.HOGDescriptor.detectMultiScale(img, hitThreshold=None, winStride=None, padding=None, scale=None, finalThreshold=None, useMeanshiftGrouping=None) -&amp;gt; foundLocations, foundWeights`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img:&amp;nbsp;입력&amp;nbsp;영상.&amp;nbsp;cv2.CV_8UC1&amp;nbsp;또는&amp;nbsp;cv2.CV_8UC3. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;hitThreshold:&amp;nbsp;특징&amp;nbsp;벡터와&amp;nbsp;SVM&amp;nbsp;분류&amp;nbsp;평면까지의&amp;nbsp;거리에&amp;nbsp;대한&amp;nbsp;임계값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;winStride:&amp;nbsp;셀&amp;nbsp;윈도우&amp;nbsp;이동&amp;nbsp;크기.&amp;nbsp;(0,&amp;nbsp;0)&amp;nbsp;지정&amp;nbsp;시&amp;nbsp;셀&amp;nbsp;크기와&amp;nbsp;같게&amp;nbsp;설정. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;padding:&amp;nbsp;패딩&amp;nbsp;크기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;scale:&amp;nbsp;검색&amp;nbsp;윈도우&amp;nbsp;크기&amp;nbsp;확대&amp;nbsp;비율.&amp;nbsp;기본값은&amp;nbsp;1.05. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;finalThreshold:&amp;nbsp;검출&amp;nbsp;결정을&amp;nbsp;위한&amp;nbsp;임계값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;useMeanshiftGrouping:&amp;nbsp;겹쳐진&amp;nbsp;검색&amp;nbsp;윈도우를&amp;nbsp;합치는&amp;nbsp;방법&amp;nbsp;지정&amp;nbsp;플래그 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;foundLocations:&amp;nbsp;(출력)&amp;nbsp;검출된&amp;nbsp;사각형&amp;nbsp;영역&amp;nbsp;정보 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;foundWeights:&amp;nbsp;(출력)&amp;nbsp;검출된&amp;nbsp;사각형&amp;nbsp;영역에&amp;nbsp;대한&amp;nbsp;신뢰도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SIFT (Scale Invariant Feature Transform)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;크기(Scale),&amp;nbsp;회전(Rotation),&amp;nbsp;조명&amp;nbsp;변화에&amp;nbsp;강인한&amp;nbsp;특징점(keypoint)을&amp;nbsp;추출하는&amp;nbsp;알고리즘 &lt;br /&gt;-&amp;nbsp;이미지에서&amp;nbsp;눈에&amp;nbsp;띄는&amp;nbsp;지점(코너,&amp;nbsp;엣지&amp;nbsp;등)을&amp;nbsp;찾고,&amp;nbsp;해당&amp;nbsp;위치에서&amp;nbsp;128차원&amp;nbsp;디스크립터를&amp;nbsp;계산함 &lt;br /&gt;-&amp;nbsp;이미지&amp;nbsp;매칭,&amp;nbsp;객체&amp;nbsp;인식&amp;nbsp;등에서&amp;nbsp;사용됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b03Y5u/btsNDxQb1b3/EYLU04KZ0dkZo7dAA1kMM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b03Y5u/btsNDxQb1b3/EYLU04KZ0dkZo7dAA1kMM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b03Y5u/btsNDxQb1b3/EYLU04KZ0dkZo7dAA1kMM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb03Y5u%2FbtsNDxQb1b3%2FEYLU04KZ0dkZo7dAA1kMM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;120&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;SIFT는&amp;nbsp;영상에서&amp;nbsp;코너점&amp;nbsp;등&amp;nbsp;식별이&amp;nbsp;용이한&amp;nbsp;특징점들을&amp;nbsp;선택한&amp;nbsp;후에&amp;nbsp;각&amp;nbsp;특징점을&amp;nbsp;중심으로&amp;nbsp;한&amp;nbsp;로컬&amp;nbsp;패치(local&amp;nbsp;patch)에&amp;nbsp;대해&amp;nbsp;아래&amp;nbsp;그림과&amp;nbsp;같은&amp;nbsp;특징&amp;nbsp;벡터를&amp;nbsp;추출한&amp;nbsp;것을&amp;nbsp;말함.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lOuh1/btsNDKIuKMD/KAGxJKuJFx8JxKLQr3kJQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lOuh1/btsNDKIuKMD/KAGxJKuJFx8JxKLQr3kJQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lOuh1/btsNDKIuKMD/KAGxJKuJFx8JxKLQr3kJQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlOuh1%2FbtsNDKIuKMD%2FKAGxJKuJFx8JxKLQr3kJQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;152&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;1)특징점&amp;nbsp;주변의&amp;nbsp;영상패치를&amp;nbsp;4&amp;nbsp;x&amp;nbsp;4&amp;nbsp;블록으로&amp;nbsp;나누고&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2)각&amp;nbsp;블록에&amp;nbsp;속한&amp;nbsp;픽셀들의&amp;nbsp;gradient&amp;nbsp;방향과&amp;nbsp;크기에&amp;nbsp;대한&amp;nbsp;히스토그램을&amp;nbsp;구한&amp;nbsp;후&amp;nbsp;이&amp;nbsp;히스토그램&amp;nbsp;bin&amp;nbsp;값들을&amp;nbsp;일렬로&amp;nbsp;쭉&amp;nbsp;연결한&amp;nbsp;128차원&amp;nbsp;벡터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Haar-like Feature (Haar Cascade)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;사각형&amp;nbsp;박스를&amp;nbsp;기준으로&amp;nbsp;밝기&amp;nbsp;차이를&amp;nbsp;비교하는&amp;nbsp;간단한&amp;nbsp;특징 &lt;br /&gt;-&amp;nbsp;빠르고&amp;nbsp;효율적이지만&amp;nbsp;딥러닝에&amp;nbsp;비해&amp;nbsp;정밀도는&amp;nbsp;낮음 &lt;br /&gt;-&amp;nbsp;주로&amp;nbsp;얼굴&amp;nbsp;검출에&amp;nbsp;사용됨&amp;nbsp;(Haar&amp;nbsp;Cascade&amp;nbsp;Classifier)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b3LJcI/btsNBxcLnp3/bL8c5MWdEDTQ0nvgfG9sYk/51_HOG.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;51_HOG.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.58MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bJJR7J/btsNEcR4WaK/T3Da5x3oz4k5HaCmUTc2hk/52_SIFT.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;52_SIFT.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.67MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/lzgam/btsNCnVjwv2/USgwkgyikKbsT86rLJsUbk/53_Haar.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;53_Haar.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bhw2JL/btsNELtTubZ/SyBfYE1q1VD8FhNHKWqEKk/01_imaging_1-Mission1.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01_imaging_1-Mission1.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cLfvv2/btsND4tTcVQ/TodKXMoSYHFzqq9WTL00tK/01_imaging_2_Mission2.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;01_imaging_2_Mission2.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cjOvB1/btsNE5ZHZYV/KkIG86Xf5cKzTIud4JiKqk/03_video_3-Mission3.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;03_video_3-Mission3.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bqcZEv/btsNFm7WS2f/klRIAwwFfZkCCAedByJrn1/04_processing_2_1-Mission4.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04_processing_2_1-Mission4.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# OpenCV를 사용하여 실시간으로 웹캠에서 움직임을 감지하고, 움직임이 일정 기준 이상 발생하면 녹화를 시작하는 프로그램&lt;br /&gt;################################################################################################ # 미션 1: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;웹캠에서&amp;nbsp;실시간으로&amp;nbsp;움직임을&amp;nbsp;감지하여&amp;nbsp;자동으로&amp;nbsp;녹화를&amp;nbsp;시작하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;움직임이&amp;nbsp;감지되면&amp;nbsp;최소&amp;nbsp;5초&amp;nbsp;동안&amp;nbsp;동영상을&amp;nbsp;저장하고,&amp;nbsp;움직임이&amp;nbsp;멈추면&amp;nbsp;녹화를&amp;nbsp;종료하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;프레임에&amp;nbsp;현재&amp;nbsp;시간을&amp;nbsp;표시하여&amp;nbsp;저장된&amp;nbsp;영상에&amp;nbsp;타임스탬프를&amp;nbsp;추가하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;결과: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;움직임&amp;nbsp;감지&amp;nbsp;결과(diff)와&amp;nbsp;현재&amp;nbsp;시간을&amp;nbsp;표시한&amp;nbsp;프레임을&amp;nbsp;화면에&amp;nbsp;출력. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 움직임이 감지되면 &quot;Recording...&quot; 메시지 출력. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;녹화된&amp;nbsp;영상&amp;nbsp;파일은&amp;nbsp;'Capture'&amp;nbsp;폴더에&amp;nbsp;저장&amp;nbsp;(예:&amp;nbsp;녹화_YYYY_MM_DD_HH_MM_SS.avi). &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;조건: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;연속된&amp;nbsp;3개의&amp;nbsp;프레임을&amp;nbsp;비교하여&amp;nbsp;움직임&amp;nbsp;감지&amp;nbsp;(absdiff&amp;nbsp;사용). &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;움직임&amp;nbsp;픽셀&amp;nbsp;수가&amp;nbsp;특정&amp;nbsp;임계값(diff_min)을&amp;nbsp;초과하면&amp;nbsp;움직임으로&amp;nbsp;간주. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;타임스탬프는&amp;nbsp;영상&amp;nbsp;상단에&amp;nbsp;표시&amp;nbsp;(PIL.ImageFont&amp;nbsp;사용). &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;주의: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;녹화&amp;nbsp;파일명에&amp;nbsp;타임스탬프를&amp;nbsp;포함하여&amp;nbsp;중복되지&amp;nbsp;않도록&amp;nbsp;설정. &lt;br /&gt;################################################################################################&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bHqXie/btsNFj4yK6K/53wm1mZ6ckofxCRCUWo2K1/cv_5-2_CCTV-motion_detection_recording-Mission1.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;cv_5-2_CCTV-motion_detection_recording-Mission1.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;################################################################################################&lt;br /&gt;#&amp;nbsp;미션&amp;nbsp;2&amp;nbsp;: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지에서&amp;nbsp;파란색,&amp;nbsp;노란색,&amp;nbsp;초록색&amp;nbsp;네모&amp;nbsp;상자를&amp;nbsp;감지하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;HSV&amp;nbsp;색상&amp;nbsp;공간에서&amp;nbsp;각&amp;nbsp;색상에&amp;nbsp;해당하는&amp;nbsp;범위를&amp;nbsp;지정하고&amp;nbsp;마스크를&amp;nbsp;생성하여&amp;nbsp;윤곽선을&amp;nbsp;감지하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;윤곽선에&amp;nbsp;대해&amp;nbsp;최소&amp;nbsp;바운딩&amp;nbsp;박스를&amp;nbsp;계산하고,&amp;nbsp;상자의&amp;nbsp;중심&amp;nbsp;좌표와&amp;nbsp;회전&amp;nbsp;각도를&amp;nbsp;구하세요. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;감지된&amp;nbsp;상자&amp;nbsp;주변에&amp;nbsp;외곽선을&amp;nbsp;색상별로&amp;nbsp;그리세요: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;파란색&amp;nbsp;상자:&amp;nbsp;파란&amp;nbsp;외곽선 &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;노란색&amp;nbsp;상자:&amp;nbsp;노란&amp;nbsp;외곽선 &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;초록색&amp;nbsp;상자:&amp;nbsp;초록&amp;nbsp;외곽선 &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;결과: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;색상의&amp;nbsp;상자&amp;nbsp;중심&amp;nbsp;좌표&amp;nbsp;및&amp;nbsp;각도를&amp;nbsp;콘솔에&amp;nbsp;출력. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이미지에&amp;nbsp;각&amp;nbsp;상자의&amp;nbsp;외곽선을&amp;nbsp;그려&amp;nbsp;시각적으로&amp;nbsp;결과를&amp;nbsp;확인. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;조건: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;HSV&amp;nbsp;색상&amp;nbsp;범위를&amp;nbsp;정확히&amp;nbsp;지정하여&amp;nbsp;노이즈를&amp;nbsp;최소화. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;윤곽선의&amp;nbsp;면적&amp;nbsp;기준(100&amp;nbsp;픽셀)으로&amp;nbsp;노이즈&amp;nbsp;필터링. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;박스는&amp;nbsp;`cv2.minAreaRect`와&amp;nbsp;`cv2.boxPoints`를&amp;nbsp;이용해&amp;nbsp;그리기. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;주의: &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;여러&amp;nbsp;색상을&amp;nbsp;한꺼번에&amp;nbsp;처리하여&amp;nbsp;코드의&amp;nbsp;효율성을&amp;nbsp;유지. &lt;br /&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;각&amp;nbsp;색상별로&amp;nbsp;구분된&amp;nbsp;결과를&amp;nbsp;명확히&amp;nbsp;표시. &lt;br /&gt;################################################################################################&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/rSwqj/btsNDIreG4t/KrfK3QCWldnkufoKR1bQfK/cv_7-4_find_and_draw_colorboxes-Mission2.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;cv_7-4_find_and_draw_colorboxes-Mission2.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;&amp;nbsp;OpenCV&amp;nbsp;얼굴인식&amp;nbsp;프로젝트1&amp;nbsp;&amp;gt; &lt;br /&gt;##&amp;nbsp;Step1&amp;nbsp;:&amp;nbsp;데이터&amp;nbsp;수집하기 &lt;br /&gt;-&amp;nbsp;웹캠에서&amp;nbsp;얼굴&amp;nbsp;부분만&amp;nbsp;검출하여&amp;nbsp;사진&amp;nbsp;100장&amp;nbsp;찍어&amp;nbsp;폴더에&amp;nbsp;저장하기 &lt;br /&gt;&lt;br /&gt;1)&amp;nbsp;cv2.CascadeClassifier()&amp;nbsp;객체&amp;nbsp;선언하기 &lt;br /&gt;2)&amp;nbsp;cv2.VideoCapture(0)&amp;nbsp;객체&amp;nbsp;선언하기 &lt;br /&gt;3)&amp;nbsp;웹캠이&amp;nbsp;열려있으면 &lt;br /&gt;-&amp;nbsp;frame&amp;nbsp;을&amp;nbsp;읽어서 &lt;br /&gt;-&amp;nbsp;회색조로&amp;nbsp;변경 &lt;br /&gt;-&amp;nbsp;detectMultiScale()&amp;nbsp;사용하여&amp;nbsp;얼굴&amp;nbsp;감지하기 &lt;br /&gt;-&amp;nbsp;감지된&amp;nbsp;얼굴에&amp;nbsp;대해&amp;nbsp;사이즈&amp;nbsp;&amp;nbsp;줄여&amp;nbsp;지정한&amp;nbsp;폴더에&amp;nbsp;구분자를&amp;nbsp;붙여&amp;nbsp;이미지로&amp;nbsp;저장하기(cv2.imwrite()) &lt;br /&gt;-&amp;nbsp;화면에는&amp;nbsp;카운트&amp;nbsp;숫자&amp;nbsp;표기하기 &lt;br /&gt;-&amp;nbsp;'q'로&amp;nbsp;종료하거나&amp;nbsp;count&amp;nbsp;가&amp;nbsp;100일때&amp;nbsp;종료하기 &lt;br /&gt;&lt;br /&gt;##&amp;nbsp;Step2&amp;nbsp;:&amp;nbsp;모델&amp;nbsp;학습하기 &lt;br /&gt;-&amp;nbsp;저장된&amp;nbsp;얼굴&amp;nbsp;이미지를&amp;nbsp;읽어서&amp;nbsp;모델&amp;nbsp;학습하기 &lt;br /&gt;1)&amp;nbsp;저장된&amp;nbsp;폴더에서&amp;nbsp;이미지를&amp;nbsp;읽어(cv2.imread()&amp;nbsp;)&amp;nbsp;회색조로&amp;nbsp;저장하기 &lt;br /&gt;2)&amp;nbsp;100장의&amp;nbsp;이미지를&amp;nbsp;리스트에&amp;nbsp;학습할&amp;nbsp;데이터(Training_Data)&amp;nbsp;와&amp;nbsp;Labels을&amp;nbsp;append&amp;nbsp;하여&amp;nbsp;각각&amp;nbsp;저장하기 &lt;br /&gt;3)&amp;nbsp;모델&amp;nbsp;객체&amp;nbsp;생성하기&amp;nbsp;:&amp;nbsp;model&amp;nbsp;=&amp;nbsp;cv2.face.LBPHFaceRecognizer_create() &lt;br /&gt;4)&amp;nbsp;모델&amp;nbsp;학습하기&amp;nbsp;:&amp;nbsp;model.train(Training_Data,&amp;nbsp;Labels) &lt;br /&gt;5)&amp;nbsp;훈련된&amp;nbsp;모델&amp;nbsp;파일로&amp;nbsp;저장하기&amp;nbsp;:model.write('face_model.yml') &lt;br /&gt;&lt;br /&gt;###&amp;nbsp;주의! &lt;br /&gt;-&amp;nbsp;&amp;nbsp;cv2.face.LBPHFaceRecognizer_create() &lt;br /&gt;을&amp;nbsp;이용해&amp;nbsp;모델을&amp;nbsp;학습시키기&amp;nbsp;할때&amp;nbsp;다음&amp;nbsp;에러&amp;nbsp;발생&amp;nbsp;시&amp;nbsp;설치하기 &lt;br /&gt;&amp;gt;&amp;nbsp;!pip&amp;nbsp;install&amp;nbsp;--user&amp;nbsp;opencv-python-headless==4.8.1.78 &lt;br /&gt;&amp;gt;&amp;nbsp;!pip&amp;nbsp;install&amp;nbsp;--user&amp;nbsp;opencv-contrib-python==4.8.1.78 &lt;br /&gt;&amp;gt;&amp;nbsp;!python&amp;nbsp;-m&amp;nbsp;pip&amp;nbsp;install&amp;nbsp;--upgrade&amp;nbsp;pip &lt;br /&gt;&amp;gt;&amp;nbsp;!pip3&amp;nbsp;install&amp;nbsp;scikit-build &lt;br /&gt;&amp;gt;&amp;nbsp;!pip&amp;nbsp;install&amp;nbsp;cmake &lt;br /&gt;&lt;br /&gt;##&amp;nbsp;Step3&amp;nbsp;:&amp;nbsp;얼굴&amp;nbsp;인식하기 &lt;br /&gt;-&amp;nbsp;분류기를&amp;nbsp;사용하여&amp;nbsp;웹캠에&amp;nbsp;비친&amp;nbsp;얼굴&amp;nbsp;중&amp;nbsp;학습한&amp;nbsp;사용자&amp;nbsp;인식하기 &lt;br /&gt;1)&amp;nbsp;cv2.CascadeClassifier()&amp;nbsp;객체&amp;nbsp;선언하기 &lt;br /&gt;2)&amp;nbsp;cv2.VideoCapture(0)&amp;nbsp;객체&amp;nbsp;선언하기 &lt;br /&gt;3)&amp;nbsp;웹캠이&amp;nbsp;열려있으면 &lt;br /&gt;-&amp;nbsp;frame&amp;nbsp;을&amp;nbsp;읽어서 &lt;br /&gt;-&amp;nbsp;회색조로&amp;nbsp;변경 &lt;br /&gt;-&amp;nbsp;detectMultiScale()&amp;nbsp;사용하여&amp;nbsp;얼굴&amp;nbsp;감지하기 &lt;br /&gt;-&amp;nbsp;얼굴이&amp;nbsp;검출된&amp;nbsp;경우 &lt;br /&gt;-&amp;nbsp;회색조로&amp;nbsp;변경하고 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;모델&amp;nbsp;예측하기&amp;nbsp;:&amp;nbsp;model.predict() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;예측&amp;nbsp;결과&amp;nbsp;신뢰도로가&amp;nbsp;75&amp;nbsp;이상인경우&amp;nbsp;화면에&amp;nbsp;&quot;ACCESS&amp;nbsp;GRANTED&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;아니면&amp;nbsp;&quot;ACCESS&amp;nbsp;DENIED&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;-&amp;nbsp;'q'로&amp;nbsp;종료 &lt;br /&gt;&lt;br /&gt;###&amp;nbsp;주의!&amp;nbsp;:&amp;nbsp;step3&amp;nbsp;에서&amp;nbsp;'AttributeError:&amp;nbsp;module&amp;nbsp;'cv2.cv2'&amp;nbsp;has&amp;nbsp;no&amp;nbsp;attribute&amp;nbsp;'face'&amp;nbsp;발생시 &lt;br /&gt;&amp;gt;&amp;nbsp;!pip&amp;nbsp;install&amp;nbsp;--user&amp;nbsp;opencv-contrib-python==4.6.0.66&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/6QLlU/btsNDG1wcNI/RmaCxh52NSN1aQXTHWKDJk/collect_faces.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;collect_faces.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dkRt9P/btsNK3239cV/z9KHYNFRfWYbZgp2azGGRk/train_model.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;train_model.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/EAgXt/btsNDcffFcf/fJgKKZCydnAH4fKfuMCJBk/face_model.yml?attach=1&amp;amp;knm=tfile.yml&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;face_model.yml&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;14.45MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cW89q3/btsNEDJyeRV/CQjluBLKE83RJUwKGjVey0/recognize_face.py?attach=1&amp;amp;knm=tfile.py&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;recognize_face.py&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/495</guid>
      <comments>https://hotari.tistory.com/495#entry495comment</comments>
      <pubDate>Tue, 29 Apr 2025 16:31:11 +0900</pubDate>
    </item>
    <item>
      <title>11일차</title>
      <link>https://hotari.tistory.com/494</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.04.28&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bz6dLz/btsNBul31sv/kc3MKbxSyvIy0J1UwsANAK/06_%EC%BB%B4%ED%93%A8%ED%84%B0%EB%B9%84%EC%A0%84.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;06_컴퓨터비전.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.98MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;창(window) 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.namedWindow(winname, flags) 함수 : winname이라는 이름을 갖는 창을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- winname : 창 구분자로 활용될 창 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- flags : 창 옵션 (cv2.WINDOW_NORMAL : 사용자가 창 크기를 조정할 수 있음,&amp;nbsp;cv2.WINDOW_AUTOSIZE : 이미지와 동일한 크기로 창 크기를 재조정할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.moveWindow(winname, x, y) 함수 : 원하는 위치로 창을 옮길 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- winname : 위치를 변경할 창 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- x, y : 변경할 위치 (x, y 좌표)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.resizeWindow(winname, width, height) 함수 : winname 창의 크기를 (width, height) 크기로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.destroyWindow(winname) 함수 : winname에 해당하는 창을 닫음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cv2.destroyAllwindows() 함수 : 열린 모든 창을 닫음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;imread() : 파일 읽기 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`image&amp;nbsp;=&amp;nbsp;cv2.imread(fileName[,&amp;nbsp;flags])`-&amp;gt;retval &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;fileName:읽어올&amp;nbsp;파일명 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;flags&amp;nbsp;:&amp;nbsp;이미지를&amp;nbsp;초기에&amp;nbsp;불러올&amp;nbsp;때&amp;nbsp;적용할&amp;nbsp;초기&amp;nbsp;상태를&amp;nbsp;의미합니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.IMREAD_UNCHANGED&amp;nbsp;:&amp;nbsp;원본&amp;nbsp;사용(-1),&amp;nbsp;alpha&amp;nbsp;channel까지&amp;nbsp;포함해읽음(png파일) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.IMREAD_GRAYSCALE&amp;nbsp;:&amp;nbsp;그레이스케일로&amp;nbsp;읽음(0),&amp;nbsp;1&amp;nbsp;채널,&amp;nbsp;실제&amp;nbsp;이미지&amp;nbsp;처리시&amp;nbsp;중간단계로&amp;nbsp;많이&amp;nbsp;사용한다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.IMREAD_COLOR&amp;nbsp;:&amp;nbsp;COLOR로&amp;nbsp;읽음(1)&amp;nbsp;,&amp;nbsp;3&amp;nbsp;채널,&amp;nbsp;투명한&amp;nbsp;부분은&amp;nbsp;무시되며,&amp;nbsp;flag디폴트&amp;nbsp;값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;imshow() : 화면 표시 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;이미지&amp;nbsp;배열을&amp;nbsp;창(window)에&amp;nbsp;표시하며,&amp;nbsp;창&amp;nbsp;이름과&amp;nbsp;이미지&amp;nbsp;데이터를&amp;nbsp;인수로&amp;nbsp;받음 &lt;br /&gt;-&amp;nbsp;이미지를&amp;nbsp;출력한&amp;nbsp;후에는&amp;nbsp;반드시&amp;nbsp;cv2.waitKey로&amp;nbsp;사용자&amp;nbsp;입력을&amp;nbsp;기다리거나,&amp;nbsp;창이&amp;nbsp;유지되어야&amp;nbsp;함함 &lt;br /&gt;-&amp;nbsp;`cv2.imshow(Title,&amp;nbsp;imageObject)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Title&amp;nbsp;(Required):&amp;nbsp;이미지를&amp;nbsp;보여주는&amp;nbsp;Window&amp;nbsp;창의&amp;nbsp;이름임. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;imageObject&amp;nbsp;(Required):&amp;nbsp;이미지&amp;nbsp;객체행렬로&amp;nbsp;cv2.imread()의&amp;nbsp;반환값을&amp;nbsp;입력하면&amp;nbsp;됨. &lt;br /&gt;-&amp;nbsp;Google&amp;nbsp;Colab에서는&amp;nbsp;cv2_imshow()&amp;nbsp;사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;imwrite() : 이미지 파일 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-cv2.imwrite(filename, img[, params])&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 이해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- shape : 이미지의 height, width, channel 정보 - 저장된 이미지의 Numpy 배열 크기(높이, 너비, 채널)&lt;/p&gt;
&lt;pre id=&quot;code_1745801118900&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;img = [
        [ [B,G,R], [B,G,R], [B,G,R], ..., [B,G,R] ],  &amp;larr; img[0]: 첫 번째 행 (y = 0)
        [ [B,G,R], [B,G,R], [B,G,R], ..., [B,G,R] ],  &amp;larr; img[1]: 두 번째 행 (y = 1)
        ...
        [ ... ]                                        &amp;larr; img[389]: 마지막 행
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온라인에 있는 이미지 파일 읽기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- JPEG 바이트 (압축된 데이터) &amp;rarr; [bytearray] &amp;rarr; cv2.imdecode() &amp;rarr; 3차원 배열 (H x W x 3)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bhpyum/btsNCnl6lBA/aROAbBF0qrtt2HaijWfhQK/11_%EC%9C%88%EB%8F%84%EC%9A%B0%26amp%3B%EC%9D%B4%EB%B2%A4%ED%8A%B8%EA%B4%80%EB%A6%AC.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;11_윈도우&amp;amp;amp;이벤트관리.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/qxNOA/btsNCvRJn8q/okAMe22smykJeyKFUJ8IoK/12_%EC%9D%B4%EB%AF%B8%EC%A7%80%20%EC%9E%85%EC%B6%9C%EB%A0%A5.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;12_이미지 입출력.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.02MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VideoCapture(index)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5dNKJ/btsNCArZZlH/wRl7Yfx1PcKYvqfw3xhfMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5dNKJ/btsNCArZZlH/wRl7Yfx1PcKYvqfw3xhfMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5dNKJ/btsNCArZZlH/wRl7Yfx1PcKYvqfw3xhfMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5dNKJ%2FbtsNCArZZlH%2FwRl7Yfx1PcKYvqfw3xhfMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;456&quot; height=&quot;178&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VideoCapture(index) 클래스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- index = 0 시스템 기본 카메라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 카메라가 열렸는지 확인&lt;/p&gt;
&lt;pre id=&quot;code_1745801580582&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if not cap.isOpened():
	print(&quot;Camera open failed!&quot;) # 열리지 않았으면 문자열 출력  
    sys.exit()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ret, frame = cap.read() # 열리지 않았으면 문자열 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- return value - true/false&lt;/p&gt;
&lt;pre id=&quot;code_1745801646568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if not ret: # 새로운 프레임을 못받아 왔을 때 braek   
   break&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bgUdiT/btsNCg1xSsS/xYbEK7pGDIqHsaFBNbWVxk/13_%EB%8F%99%EC%98%81%EC%83%81%20%EC%9E%85%EC%B6%9C%EB%A0%A5.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;13_동영상 입출력.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도형 그리기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 스케치북 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;크기와&amp;nbsp;초깃값으로&amp;nbsp;생성&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;Numpy&amp;nbsp;배열을&amp;nbsp;생성할&amp;nbsp;때&amp;nbsp;사용할&amp;nbsp;값을&amp;nbsp;가지고&amp;nbsp;있지&amp;nbsp;않은&amp;nbsp;경우가&amp;nbsp;많기&amp;nbsp;때문에&amp;nbsp;초기&amp;nbsp;값을&amp;nbsp;지정해서&amp;nbsp;생성하는&amp;nbsp;방법을&amp;nbsp;사용 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.empty(shape&amp;nbsp;[,&amp;nbsp;dtype])&amp;nbsp;:&amp;nbsp;초기화되지&amp;nbsp;않는&amp;nbsp;값(쓰레기&amp;nbsp;값)으로&amp;nbsp;배열&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.zeros(shape&amp;nbsp;[,dtype])&amp;nbsp;:&amp;nbsp;0으로&amp;nbsp;초기화된&amp;nbsp;배열&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.ones(shape&amp;nbsp;[,dtype])&amp;nbsp;:&amp;nbsp;1로&amp;nbsp;초기화된&amp;nbsp;배열&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- numpy.full(shape, fill_value [,dtype]) : fill_value로 초기화된 배열 생성&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;시퀀스와&amp;nbsp;난수로&amp;nbsp;생성 &lt;br /&gt;Numpy&amp;nbsp;배열을&amp;nbsp;생성하는&amp;nbsp;방법&amp;nbsp;중에는&amp;nbsp;일정한&amp;nbsp;범위&amp;nbsp;내에서&amp;nbsp;순차적인&amp;nbsp;값을&amp;nbsp;갖게하는&amp;nbsp;방법과&amp;nbsp;난수로&amp;nbsp;채우는&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.arange([start=0,&amp;nbsp;]&amp;nbsp;stop&amp;nbsp;[,&amp;nbsp;step=1,&amp;nbsp;dtype&amp;nbsp;=&amp;nbsp;float64])&amp;nbsp;:&amp;nbsp;순차적인&amp;nbsp;값으로&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;start&amp;nbsp;:&amp;nbsp;시작&amp;nbsp;값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;stop&amp;nbsp;:&amp;nbsp;종료&amp;nbsp;값,&amp;nbsp;범위에&amp;nbsp;포함되는&amp;nbsp;수는&amp;nbsp;~&amp;nbsp;stop&amp;nbsp;-1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;step&amp;nbsp;:&amp;nbsp;증가&amp;nbsp;값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;dtype&amp;nbsp;:&amp;nbsp;데이터&amp;nbsp;타입 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.random.rand(array크기)&amp;nbsp;:&amp;nbsp;0과&amp;nbsp;1&amp;nbsp;사이의&amp;nbsp;무작위&amp;nbsp;수&amp;nbsp;생성 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;array크기를&amp;nbsp;생략하면&amp;nbsp;난수&amp;nbsp;1개&amp;nbsp;반환,&amp;nbsp;나머지는&amp;nbsp;해당&amp;nbsp;크기만큼&amp;nbsp;값을&amp;nbsp;반환 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;numpy.random.randn(array크기)&amp;nbsp;:&amp;nbsp;표준&amp;nbsp;정규&amp;nbsp;분포를&amp;nbsp;따르는&amp;nbsp;무작위&amp;nbsp;수&amp;nbsp;생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직선&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직선의 종류(line type)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. cv2.LINE_4 : 상하좌우 4 방향으로 연결된 선&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. cv2.LINE_8 : 대각선을 포함한 8방향으로 연결된 선(기본값)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. cv2.LINE_AA : 부드러운 선(anit-aliasing)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oH1pQ/btsNAXop2aS/vsV0rgPikGmKkh4c5jCRd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oH1pQ/btsNAXop2aS/vsV0rgPikGmKkh4c5jCRd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oH1pQ/btsNAXop2aS/vsV0rgPikGmKkh4c5jCRd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoH1pQ%2FbtsNAXop2aS%2FvsV0rgPikGmKkh4c5jCRd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;517&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;517&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림판에서 확인 : 그림판은 LINE_8을 사용하고 있음(확대하면 확인 가능)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjlKzM/btsNAGU557C/AAviIHs0DAUPNB3ARLAPEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjlKzM/btsNAGU557C/AAviIHs0DAUPNB3ARLAPEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjlKzM/btsNAGU557C/AAviIHs0DAUPNB3ARLAPEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjlKzM%2FbtsNAGU557C%2FAAviIHs0DAUPNB3ARLAPEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;638&quot; height=&quot;440&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/z7h7Q/btsNBa15ud1/wclYcTQoiPYnxv3W7eyjx0/14_%EB%8F%84%ED%98%95%EA%B7%B8%EB%A6%AC%EA%B8%B0.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;14_도형그리기.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;cv2.putText(img,&amp;nbsp;'Coding&amp;nbsp;Simplex',&amp;nbsp;(20,&amp;nbsp;50),&amp;nbsp;cv2.FONT_HERSHEY_SIMPLEX,&amp;nbsp;SCALE,&amp;nbsp;COLOR,&amp;nbsp;THICKNESS) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;그릴&amp;nbsp;위치,&amp;nbsp;텍스트&amp;nbsp;내용,&amp;nbsp;시작위치,&amp;nbsp;폰트&amp;nbsp;종류,&amp;nbsp;크기,&amp;nbsp;색깔,&amp;nbsp;두께 &lt;br /&gt;&lt;br /&gt;OpenCV에서 사용하는 글꼴 종류&lt;br /&gt;1.&amp;nbsp;cv2.FONT_HERSHEY_SIMPLEX&amp;nbsp;:&amp;nbsp;보통&amp;nbsp;크기의&amp;nbsp;산&amp;nbsp;세리프(sans-serif)글꼴 &lt;br /&gt;2. cv2.FONT_HERSHEY_PLAIN : 작은 크기의 산 세리프 글꼴 &lt;br /&gt;3. cv2.FONT_HERSHEY_SCRIPT_SIMPLEX : 필기체 스타일 글꼴 &lt;br /&gt;4. cv2.FONT_HERSHEY_TRIPLEX : 보통 크기의 산 세리프 글꼴 &lt;br /&gt;5. cv2.FONT_ITALIC : 기울림(이탤릭체)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bz6veY/btsNCCDmZ8n/kegLwt3gjeTqzBTxQDzCsk/15_%ED%85%8D%EC%8A%A4%ED%8A%B8.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;15_텍스트.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관심 영역(Region of Interest, ROI)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지 내에서 원하는 피사체를 따로 분리하여 특정 처리를 하고싶을 때 사용하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 연산할 데이터의 양을 줄이고 수행 시간을 단축시키기 때문에 특정 연산을 적용해 새로운 이미지와 정보를 획득할 때 전체 이미지로 연산을 하는 것보다 관심이 있는 부분만 연산하는 것이 효과적임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Numpy 이용한 ROI 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 함수 활용하여 ROI 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`cv2.selectROI([win_name,],&amp;nbsp;img[,showCrossHair=True,&amp;nbsp;fromCenter=False])` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;win_name&amp;nbsp;:&amp;nbsp;ROI&amp;nbsp;선택을&amp;nbsp;진행할&amp;nbsp;창의&amp;nbsp;이름 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img&amp;nbsp;:&amp;nbsp;ROI&amp;nbsp;선택을&amp;nbsp;진행할&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;showCrossHair&amp;nbsp;:&amp;nbsp;선택&amp;nbsp;영역&amp;nbsp;중심에&amp;nbsp;십자&amp;nbsp;모양&amp;nbsp;표시&amp;nbsp;여부 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;fromCenter&amp;nbsp;:&amp;nbsp;마우스&amp;nbsp;시작&amp;nbsp;지점을&amp;nbsp;영역의&amp;nbsp;중심으로&amp;nbsp;지정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ret&amp;nbsp;:&amp;nbsp;선택한&amp;nbsp;영역&amp;nbsp;좌표와&amp;nbsp;크기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cRxFps/btsNA3oCmZH/rIWnyVoOKtYfVpaK1nL6l0/21_%EA%B4%80%EC%8B%AC%EC%98%81%EC%97%AD.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;21_관심영역.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.82MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지색 공간변환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;색공간 변환하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;cv2.cvtColor(img,&amp;nbsp;옵션값)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;색상&amp;nbsp;공간&amp;nbsp;변환(Convert&amp;nbsp;Color)은&amp;nbsp;본래의&amp;nbsp;색상&amp;nbsp;공간에서&amp;nbsp;다른&amp;nbsp;색상&amp;nbsp;공간으로&amp;nbsp;변환할&amp;nbsp;때&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;입력된&amp;nbsp;이미지는&amp;nbsp;8&amp;nbsp;비트,&amp;nbsp;16&amp;nbsp;비트,&amp;nbsp;32&amp;nbsp;비트의&amp;nbsp;정밀도를&amp;nbsp;갖는&amp;nbsp;배열을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;데이터&amp;nbsp;값이&amp;nbsp;변경되거나&amp;nbsp;채널&amp;nbsp;순서가&amp;nbsp;변경될&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;COLOR_BGR2GRAY,&amp;nbsp;COLOR_GRAY2BGR,&amp;nbsp;COLOR_RGB2GRAY,&amp;nbsp;COLOR_GRAY2RGB...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주피터 노트북에 나타내기 - matplotlib 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;OpenCV&amp;nbsp;:&amp;nbsp;다차원&amp;nbsp;NumPy&amp;nbsp;배열로&amp;nbsp;RGB&amp;nbsp;영상을&amp;nbsp;표현하지만&amp;nbsp;순서가&amp;nbsp;BRG로&amp;nbsp;반대임 &lt;br /&gt;-&amp;nbsp;&amp;lt;b&amp;gt;&amp;nbsp;Matplotlib&amp;nbsp;에서&amp;nbsp;opencv&amp;nbsp;로&amp;nbsp;읽은&amp;nbsp;파일&amp;nbsp;사용하려면&amp;nbsp;BGR을&amp;nbsp;RGB로&amp;nbsp;순서&amp;nbsp;변경하고&amp;nbsp;그래프를&amp;nbsp;그려야함&amp;nbsp;&amp;lt;/b&amp;gt; &lt;br /&gt;-&amp;nbsp;`plt.imshow&amp;nbsp;(src,&amp;nbsp;cmap='plt.cm.원하는&amp;nbsp;색깔',&amp;nbsp;interpolation='')`&amp;nbsp; &lt;br /&gt;2차원&amp;nbsp;배열&amp;nbsp;객체를&amp;nbsp;색깔로&amp;nbsp;표시해하는&amp;nbsp;이미지를&amp;nbsp;출력할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;함수임.&amp;nbsp; &lt;br /&gt;[Interpolations&amp;nbsp;for&amp;nbsp;imshow](&amp;nbsp;&lt;a href=&quot;https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html)&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;`plt.show()`&amp;nbsp;&amp;nbsp; &lt;br /&gt;그림을&amp;nbsp;표시하고&amp;nbsp;사용&amp;nbsp;중인&amp;nbsp;GUI&amp;nbsp;백엔드의&amp;nbsp;메인&amp;nbsp;루프로&amp;nbsp;들어갑니다.&amp;nbsp;플롯을&amp;nbsp;만들고&amp;nbsp;표시되는&amp;nbsp;것을&amp;nbsp;보고&amp;nbsp;싶을&amp;nbsp;때까지&amp;nbsp;호출하면&amp;nbsp;안&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/lYxgF/btsNALu7wHn/6Fg0IRNWKPoL4uaimq06C0/22_%EC%9D%B4%EB%AF%B8%EC%A7%80%EC%83%89%EA%B3%B5%EA%B0%84%EB%B3%80%ED%99%98.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;22_이미지색공간변환.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.12MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크기 조정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;`cv2.resize(원본이미지,&amp;nbsp;(new_width,&amp;nbsp;new_height))`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img.shape&amp;nbsp;&amp;rarr;&amp;nbsp;(height,&amp;nbsp;width,&amp;nbsp;channels)&amp;nbsp;:&amp;nbsp;(width,&amp;nbsp;height)&amp;nbsp;순서로&amp;nbsp;지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보간법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 변경할 때 자연스럽게 하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. cv2.INTER_AREA : 크기 줄일 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. cv2.INTER_CUBIC : 크기 늘일 때 사용 (속도 느림, 퀄리티 좋음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. cv2.INTER_LINEAR : 크기 늘릴 때 사용 (기본값)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dUQMpE/btsNBCD4EWy/is6vlO0uYgoYbnJ6nLdI7k/31_%ED%81%AC%EA%B8%B0%EC%A1%B0%EC%A0%95.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;31_크기조정.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 연산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트와이즈(bitwise) 연산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;bitwise_and(img1,&amp;nbsp;img2,&amp;nbsp;mask=None)&amp;nbsp;:&amp;nbsp;각&amp;nbsp;픽셀에&amp;nbsp;대한&amp;nbsp;비트와이즈&amp;nbsp;AND&amp;nbsp;연산 &lt;br /&gt;-&amp;nbsp;bitwise_or(img1,&amp;nbsp;img2,&amp;nbsp;mask=None)&amp;nbsp;:&amp;nbsp;각&amp;nbsp;픽셀에&amp;nbsp;대한&amp;nbsp;비트와이즈&amp;nbsp;OR&amp;nbsp;연산 &lt;br /&gt;-&amp;nbsp;bitwise_xor(img1,&amp;nbsp;img2,&amp;nbsp;mask=None)&amp;nbsp;:&amp;nbsp;각&amp;nbsp;픽셀에&amp;nbsp;대한&amp;nbsp;비트와이즈&amp;nbsp;XOR&amp;nbsp;연산 &lt;br /&gt;-&amp;nbsp;bitwise_not(img1,&amp;nbsp;mask=None)&amp;nbsp;:&amp;nbsp;각&amp;nbsp;픽셀에&amp;nbsp;대한&amp;nbsp;비트와이즈&amp;nbsp;NOT&amp;nbsp;연산&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/kNh4G/btsNDvcFbrm/cjLiYbOAwVp7BxCqz10QT1/23_%EC%9D%B4%EB%AF%B8%EC%A7%80%EC%97%B0%EC%82%B0.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;23_이미지연산.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.70MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 변형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이진화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;이진화(Binary)는&amp;nbsp;어느&amp;nbsp;지점을&amp;nbsp;기준으로&amp;nbsp;값이&amp;nbsp;높거나&amp;nbsp;낮은&amp;nbsp;픽셀의&amp;nbsp;값을&amp;nbsp;대상으로&amp;nbsp;특정&amp;nbsp;연산을&amp;nbsp;수행할&amp;nbsp;때&amp;nbsp;사용 &lt;br /&gt;- 일반적으로 값이 높거나 낮은 픽셀을 검은색 또는 흰색의 값으로 변경&lt;br /&gt;- 기준값에 따라 이분법적으로 구분해 픽셀을 참 또는 거짓으로 나누는 연산이며, 이미지 행렬에서 모든 픽셀에 대해 연산이 수행됩니다.&lt;br /&gt;-&amp;nbsp;이진화하면&amp;nbsp;어떠한&amp;nbsp;경곗값을&amp;nbsp;기준으로&amp;nbsp;이진화하면&amp;nbsp;물체가&amp;nbsp;선명(뚜렷해짐)해지고&amp;nbsp;처리해야할&amp;nbsp;화소가&amp;nbsp;줄게되어&amp;nbsp;영상의&amp;nbsp;용량도&amp;nbsp;줄어듬&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임계처리(Thresholing)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;임계처리(thresholding)는&amp;nbsp;이미지&amp;nbsp;행렬에서&amp;nbsp;하나의&amp;nbsp;픽셀값을&amp;nbsp;사용자가&amp;nbsp;지정한&amp;nbsp;기준값(threshold)를&amp;nbsp;사용하여&amp;nbsp;이진화(binarization)하는&amp;nbsp;가장&amp;nbsp;단순한&amp;nbsp;필터임.&amp;nbsp;이진화는&amp;nbsp;이름에서&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있듯이,&amp;nbsp;영상(사진)을&amp;nbsp;이진법처럼&amp;nbsp;두&amp;nbsp;가지로만&amp;nbsp;분류하는&amp;nbsp;것입니다.&amp;nbsp; &lt;br /&gt;- openCV에서 이진화는 기존의 영상을 검은색과 흰색으로만 이루어진 영상으로 바꾸어주는 작업&lt;br /&gt;- &amp;lt;font color=blue&amp;gt;임계처리(thresholding)는 이미지를 그레이스케일로 변환한 후에 주로 수행&amp;lt;/font&amp;gt;됩니다.&lt;br /&gt;- `ret, dst = threshold(src, thresh, maxval, type)`&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;src&amp;nbsp;:&amp;nbsp;그레이&amp;nbsp;스케일&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;thresh&amp;nbsp;:&amp;nbsp;기준값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;maxval&amp;nbsp;:&amp;nbsp;기준값을&amp;nbsp;넘었을&amp;nbsp;때&amp;nbsp;적용할&amp;nbsp;최대값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;type&amp;nbsp;:&amp;nbsp;임계처리&amp;nbsp;유형 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;THRESH_BINARY&amp;nbsp;:&amp;nbsp;임계값&amp;nbsp;이상&amp;nbsp;=&amp;nbsp;최댓값,&amp;nbsp;임계값&amp;nbsp;이하&amp;nbsp;=&amp;nbsp;0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;THRESH_BINARY_INV&amp;nbsp;:&amp;nbsp;위의&amp;nbsp;반전,&amp;nbsp;임계값&amp;nbsp;이상&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;임계값&amp;nbsp;이하&amp;nbsp;=&amp;nbsp;최댓값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;THRESH_TRUNC&amp;nbsp;:&amp;nbsp;임계값&amp;nbsp;이상&amp;nbsp;=&amp;nbsp;임계값,&amp;nbsp;임계값&amp;nbsp;이하&amp;nbsp;=&amp;nbsp;원본값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;THRESH_TOZERO&amp;nbsp;:&amp;nbsp;임계값&amp;nbsp;이상&amp;nbsp;=&amp;nbsp;원본값,&amp;nbsp;임계값&amp;nbsp;이하&amp;nbsp;=&amp;nbsp;0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- THRESH_TOZERO_INV : 위의 반전, 임계값 이상 = 0, 임계값 이하 = 원본값&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVg5w/btsNBa18RJ5/L764kAYU3ychKzepLxKv60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVg5w/btsNBa18RJ5/L764kAYU3ychKzepLxKv60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVg5w/btsNBa18RJ5/L764kAYU3ychKzepLxKv60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVg5w%2FbtsNBa18RJ5%2FL764kAYU3ychKzepLxKv60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;287&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ret&amp;nbsp;:&amp;nbsp;임계값&amp;nbsp;반환 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;dst&amp;nbsp;:&amp;nbsp;이진화된&amp;nbsp;영상이&amp;nbsp;저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adaptive Threshold (적응형 스레스홀딩)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;이미지를&amp;nbsp;작은&amp;nbsp;영역으로&amp;nbsp;나누어서&amp;nbsp;임계치&amp;nbsp;적용&amp;nbsp;-&amp;nbsp;이진화&amp;nbsp;처리가&amp;nbsp;어려운경우 &lt;br /&gt;(한쪽은 밝거나 한쪽은 어두운경우, 반사가 심하거나조명이 일정하지 않아 밝고 어둡고 한경우)&lt;br /&gt;-&amp;nbsp;`cv2.adaptiveThreshold(img,&amp;nbsp;value,&amp;nbsp;method,&amp;nbsp;type_flag,&amp;nbsp;block_size,&amp;nbsp;C)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img:&amp;nbsp;원본&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;value:&amp;nbsp;임계값을&amp;nbsp;만족하는&amp;nbsp;픽셀에&amp;nbsp;적용할&amp;nbsp;값 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;method:&amp;nbsp;임계값&amp;nbsp;설정&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.ADAPTIVE_THRESH_MEAN_C:&amp;nbsp;이웃&amp;nbsp;픽셀의&amp;nbsp;평균으로&amp;nbsp;결정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;cv2.ADAPTIVE_THRESH_GAUSSIAN_C:&amp;nbsp;가우시안&amp;nbsp;분포에&amp;nbsp;따른&amp;nbsp;가중치의&amp;nbsp;합으로&amp;nbsp;결정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;type_flag:&amp;nbsp;스레시홀딩&amp;nbsp;적용&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;block_size:&amp;nbsp;영역으로&amp;nbsp;나눌&amp;nbsp;이웃의&amp;nbsp;크기(n&amp;nbsp;x&amp;nbsp;n),&amp;nbsp;홀수 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;C:&amp;nbsp;계산된&amp;nbsp;임계값&amp;nbsp;결과에서&amp;nbsp;가감할&amp;nbsp;상수(음수&amp;nbsp;가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오츠 알고리즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적의 임계값 찾기 - trackbar 사용 안해도 됨 모든 이미지에 최적의 임계값을 찾는 건 아님 Bimodal Image에 사용하기에 적합(최적의 임계치를 자동으로 발견)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/uyNxh/btsNDnZ9uas/0VtFd8DAgkOI9QF66kmnIK/24_%EC%9E%84%EA%B3%84%EC%B2%98%EB%A6%AC.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;24_임계처리.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.02MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토그램 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 히스토그램은 특정한 값을 가진 화소가 영상 안에 몇 개나 있는지를 막대그래프로 표시한 것으로 이미지의 픽셀 값(밝기 또는 색상)을 X축으로, 해당 값을 가진 픽셀의 개수를 Y축으로 표현합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TD60s/btsNBGfzfCU/1n3NsRo6Arnb39RmfDJk70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TD60s/btsNBGfzfCU/1n3NsRo6Arnb39RmfDJk70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TD60s/btsNBGfzfCU/1n3NsRo6Arnb39RmfDJk70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTD60s%2FbtsNBGfzfCU%2F1n3NsRo6Arnb39RmfDJk70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;156&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;그레이스케일&amp;nbsp;히스토그램:&amp;nbsp;0(검정)부터&amp;nbsp;255(흰색)까지의&amp;nbsp;밝기&amp;nbsp;값&amp;nbsp;분포를&amp;nbsp;보여줍니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;컬러&amp;nbsp;히스토그램:&amp;nbsp;RGB&amp;nbsp;각&amp;nbsp;채널별로&amp;nbsp;별도의&amp;nbsp;히스토그램이&amp;nbsp;존재합니다 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;히스토그램으로&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;정보 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;전체&amp;nbsp;밝기&amp;nbsp;분포:&amp;nbsp;이미지가&amp;nbsp;전반적으로&amp;nbsp;어두운지,&amp;nbsp;밝은지,&amp;nbsp;중간&amp;nbsp;톤인지&amp;nbsp;판단할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;대비(Contrast):&amp;nbsp;히스토그램이&amp;nbsp;넓게&amp;nbsp;분포되어&amp;nbsp;있으면&amp;nbsp;대비가&amp;nbsp;높고,&amp;nbsp;좁게&amp;nbsp;모여있으면&amp;nbsp;대비가&amp;nbsp;낮습니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;노출&amp;nbsp;상태:&amp;nbsp;히스토그램이&amp;nbsp;오른쪽으로&amp;nbsp;치우쳐&amp;nbsp;있으면&amp;nbsp;과노출,&amp;nbsp;왼쪽으로&amp;nbsp;치우쳐&amp;nbsp;있으면&amp;nbsp;저노출입니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;다이내믹&amp;nbsp;레인지:&amp;nbsp;픽셀&amp;nbsp;값이&amp;nbsp;분포된&amp;nbsp;범위로,&amp;nbsp;이미지가&amp;nbsp;표현하는&amp;nbsp;밝기의&amp;nbsp;범위를&amp;nbsp;나타냅니다.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;이미지&amp;nbsp;유형에&amp;nbsp;따른&amp;nbsp;히스토그램&amp;nbsp;해석석 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;1.&amp;nbsp;일반적인&amp;nbsp;고품질&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;픽셀&amp;nbsp;값이&amp;nbsp;전체&amp;nbsp;범위(0~255)에&amp;nbsp;골고루&amp;nbsp;분포 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;양&amp;nbsp;끝(0이나&amp;nbsp;255)에&amp;nbsp;과도하게&amp;nbsp;집중되지&amp;nbsp;않음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;2.&amp;nbsp;저대비&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;중앙&amp;nbsp;부분에&amp;nbsp;좁게&amp;nbsp;집중됨 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;검정과&amp;nbsp;흰색&amp;nbsp;부분이&amp;nbsp;거의&amp;nbsp;없고&amp;nbsp;회색조가&amp;nbsp;대부분 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;3.&amp;nbsp;고대비&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;넓은&amp;nbsp;범위에&amp;nbsp;분포함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;어두운&amp;nbsp;부분과&amp;nbsp;밝은&amp;nbsp;부분의&amp;nbsp;차이가&amp;nbsp;뚜렷함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;4.&amp;nbsp;저노출(어두운)&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;왼쪽(어두운&amp;nbsp;부분)에&amp;nbsp;집중됨 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;오른쪽&amp;nbsp;부분(밝은&amp;nbsp;값)이&amp;nbsp;거의&amp;nbsp;비어있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;5.&amp;nbsp;과노출(밝은)&amp;nbsp;이미지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;오른쪽(밝은&amp;nbsp;부분)에&amp;nbsp;집중됨 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;왼쪽&amp;nbsp;부분(어두운&amp;nbsp;값)이&amp;nbsp;거의&amp;nbsp;비어있음&amp;nbsp; &lt;br /&gt;&lt;br /&gt;- cv2.calcHist(img, channel, mask, histSize, ranges)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img:&amp;nbsp;히스토그램을&amp;nbsp;구하고&amp;nbsp;싶은&amp;nbsp;이미지&amp;nbsp;영상,&amp;nbsp;[img]와&amp;nbsp;같이&amp;nbsp;리스트로&amp;nbsp;입력해주어야&amp;nbsp;함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;channel:&amp;nbsp;히스토그램을&amp;nbsp;구할&amp;nbsp;영상의&amp;nbsp;채널,&amp;nbsp;grayscale&amp;nbsp;이미지의&amp;nbsp;경우&amp;nbsp;[0]을&amp;nbsp;인자로&amp;nbsp;입력하고&amp;nbsp;color&amp;nbsp;이미지일&amp;nbsp;경우&amp;nbsp;B,&amp;nbsp;G,&amp;nbsp;R에&amp;nbsp;대한&amp;nbsp;히스토그램을&amp;nbsp;구하기&amp;nbsp;위해서&amp;nbsp;[0],&amp;nbsp;[1],&amp;nbsp;[2]를&amp;nbsp;인자로&amp;nbsp;입력 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;mask:&amp;nbsp;히스토그램을&amp;nbsp;구할&amp;nbsp;영역을&amp;nbsp;지정하는&amp;nbsp;마스크,&amp;nbsp;None을&amp;nbsp;입력하면&amp;nbsp;전체&amp;nbsp;영상에서&amp;nbsp;히스토그램을&amp;nbsp;구함 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;histSize:&amp;nbsp;히스토그램의&amp;nbsp;칸의&amp;nbsp;수를&amp;nbsp;지정,&amp;nbsp;보통&amp;nbsp;한&amp;nbsp;pixel당&amp;nbsp;0~255까지의&amp;nbsp;값을&amp;nbsp;가져&amp;nbsp;명암단계가&amp;nbsp;L&amp;nbsp;=&amp;nbsp;256이기&amp;nbsp;때문에&amp;nbsp;[256]과&amp;nbsp;같이&amp;nbsp;리스트로&amp;nbsp;전달해주면&amp;nbsp;됨.&amp;nbsp;128로&amp;nbsp;지정하면&amp;nbsp;0과&amp;nbsp;1을&amp;nbsp;0,&amp;nbsp;2와&amp;nbsp;3을&amp;nbsp;1,&amp;nbsp;...로&amp;nbsp;간주해&amp;nbsp;128개의&amp;nbsp;칸을&amp;nbsp;가진&amp;nbsp;히스토그램을&amp;nbsp;구함. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;ranges:&amp;nbsp;각&amp;nbsp;픽셀값이&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;범위,&amp;nbsp;보통&amp;nbsp;[0,256]으로&amp;nbsp;지정,&amp;nbsp;만약&amp;nbsp;[0,128]로&amp;nbsp;지정했다면&amp;nbsp;128&amp;nbsp;이상인&amp;nbsp;값은&amp;nbsp;세지&amp;nbsp;않음. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;cv2.equalizeHist()&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dJkUfX/btsNALBTlJH/J8tnZ7bbK9n331cis6BC31/25_%ED%9E%88%EC%8A%A4%ED%86%A0%EA%B7%B8%EB%9E%A8%EB%B6%84%EC%84%9D.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;25_히스토그램분석.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.38MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토그램 평활화(Histogram Equalization)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;특정&amp;nbsp;영역에&amp;nbsp;집중되어&amp;nbsp;있는&amp;nbsp;영상의&amp;nbsp;히스토그램&amp;nbsp;분포를&amp;nbsp;평평하게&amp;nbsp;만들어&amp;nbsp;명암&amp;nbsp;대비를&amp;nbsp;높이는&amp;nbsp;기법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;명암&amp;nbsp;값이&amp;nbsp;몰려&amp;nbsp;있어서&amp;nbsp;어둡기만&amp;nbsp;한&amp;nbsp;영상&amp;nbsp;또는&amp;nbsp;밝기만&amp;nbsp;한&amp;nbsp;영상을&amp;nbsp;평활화하여&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;선명한&amp;nbsp;영상을&amp;nbsp;얻음음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;영상의&amp;nbsp;명암&amp;nbsp;대비가&amp;nbsp;높아지면&amp;nbsp;영상에&amp;nbsp;있는&amp;nbsp;물체를&amp;nbsp;더&amp;nbsp;잘&amp;nbsp;식별할&amp;nbsp;수&amp;nbsp;있게됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zubXA/btsNAY9ekfg/sp0FTjoqvH22kUPqXpJNmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zubXA/btsNAY9ekfg/sp0FTjoqvH22kUPqXpJNmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zubXA/btsNAY9ekfg/sp0FTjoqvH22kUPqXpJNmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzubXA%2FbtsNAY9ekfg%2Fsp0FTjoqvH22kUPqXpJNmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;283&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JUrgV/btsNC9nPyrR/iCo8f7WXnVco3aUZXXOgY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JUrgV/btsNC9nPyrR/iCo8f7WXnVco3aUZXXOgY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JUrgV/btsNC9nPyrR/iCo8f7WXnVco3aUZXXOgY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJUrgV%2FbtsNC9nPyrR%2FiCo8f7WXnVco3aUZXXOgY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;228&quot; height=&quot;35&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;&amp;nbsp;L&amp;nbsp;=&amp;nbsp;8인&amp;nbsp;4&amp;nbsp;x&amp;nbsp;4&amp;nbsp;크기의&amp;nbsp;영상&amp;nbsp;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1)&amp;nbsp;계산된&amp;nbsp;히스토그램&amp;nbsp;분포&amp;nbsp;h(g)에&amp;nbsp;전체&amp;nbsp;크기인&amp;nbsp;16씩을&amp;nbsp;나눠주어&amp;nbsp;정규화&amp;nbsp;히스토그램&amp;nbsp;p(g)를&amp;nbsp;계산&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2)&amp;nbsp;각&amp;nbsp;명암값&amp;nbsp;별로&amp;nbsp;이전까지의&amp;nbsp;정규화&amp;nbsp;히스토그램&amp;nbsp;p(g)값을&amp;nbsp;합쳐&amp;nbsp;누적&amp;nbsp;정규화&amp;nbsp;히스토그램&amp;nbsp;cdf(g)를&amp;nbsp;계산&amp;nbsp;:&amp;nbsp;마지막&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3)&amp;nbsp;각&amp;nbsp;누적&amp;nbsp;정규화&amp;nbsp;히스토그램&amp;nbsp;값&amp;nbsp;cdf(g)에&amp;nbsp;최대&amp;nbsp;명암값(LmaxLmaxL_{max})인&amp;nbsp;7씩을&amp;nbsp;곱하고&amp;nbsp;반올림&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;이미지의&amp;nbsp;전반적인&amp;nbsp;대비를&amp;nbsp;개선하기&amp;nbsp;위해&amp;nbsp;사용되는&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;특정&amp;nbsp;밝기&amp;nbsp;계급에&amp;nbsp;픽셀이&amp;nbsp;지나치게&amp;nbsp;집중되어&amp;nbsp;있을&amp;nbsp;때,&amp;nbsp;이&amp;nbsp;방식은&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;문제점을&amp;nbsp;초래할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들면,&amp;nbsp;평활화&amp;nbsp;후의&amp;nbsp;이미지에서&amp;nbsp;나머지&amp;nbsp;계급의&amp;nbsp;세부&amp;nbsp;정보가&amp;nbsp;손실되거나,&amp;nbsp;비자연스러운&amp;nbsp;노이즈나&amp;nbsp;패턴이&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;히스토그램&amp;nbsp;매칭(Histogram&amp;nbsp;Matching)은&amp;nbsp;원하는&amp;nbsp;히스토그램&amp;nbsp;분포를&amp;nbsp;가진&amp;nbsp;참조&amp;nbsp;이미지를&amp;nbsp;사용하여,&amp;nbsp;타겟&amp;nbsp;이미지의&amp;nbsp;분포를&amp;nbsp;조정하는&amp;nbsp;방법(입력&amp;nbsp;이미지에&amp;nbsp;참조&amp;nbsp;이미지의&amp;nbsp;색감을&amp;nbsp;입히는&amp;nbsp;기법) &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;**히스토그램&amp;nbsp;평활화&amp;nbsp;효과** &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램이&amp;nbsp;너무&amp;nbsp;한쪽(어두운&amp;nbsp;쪽)에&amp;nbsp;몰려&amp;nbsp;있으면&amp;nbsp;전체적으로&amp;nbsp;밝게&amp;nbsp;펴주는&amp;nbsp;효과가&amp;nbsp;있음&amp;nbsp;=&amp;gt;&amp;nbsp;하지만&amp;nbsp;무조건&amp;nbsp;밝게&amp;nbsp;만드는&amp;nbsp;게&amp;nbsp;아니라,&amp;nbsp;명암&amp;nbsp;대비(contrast)를&amp;nbsp;전체적으로&amp;nbsp;넓게&amp;nbsp;분포시키는&amp;nbsp;게&amp;nbsp;목적임. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;히스토그램&amp;nbsp;평활화는&amp;nbsp;밝고&amp;nbsp;어두운&amp;nbsp;영역의&amp;nbsp;구분을&amp;nbsp;명확하게&amp;nbsp;해줍니다.&amp;nbsp;=&amp;gt;&amp;nbsp;흐릿하거나&amp;nbsp;뿌연&amp;nbsp;이미지를&amp;nbsp;더&amp;nbsp;뚜렷하게(선명하게)&amp;nbsp;보이게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;`cv2.equalizeHist(img,&amp;nbsp;dst)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;img:&amp;nbsp;히스토그램&amp;nbsp;평활화를&amp;nbsp;적용시키고자&amp;nbsp;하는&amp;nbsp;영상&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;dst:&amp;nbsp;결과&amp;nbsp;이미지(입력&amp;nbsp;안해도됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토그램 평활화 : 컬러 이미지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;컬러영상에&amp;nbsp;히스토그램&amp;nbsp;평활화를&amp;nbsp;적용할&amp;nbsp;때&amp;nbsp;RGB&amp;nbsp;채널&amp;nbsp;각각에&amp;nbsp;히스토그램&amp;nbsp;평활화를&amp;nbsp;적용한&amp;nbsp;후&amp;nbsp;합치면&amp;nbsp;색이&amp;nbsp;변하는&amp;nbsp;문제가&amp;nbsp;일어날&amp;nbsp;수&amp;nbsp;있음(색이&amp;nbsp;왜곡되어&amp;nbsp;부자연스러운&amp;nbsp;이미지가&amp;nbsp;되기&amp;nbsp;때문) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;RGB는&amp;nbsp;색상(Hue),&amp;nbsp;명도(Value),&amp;nbsp;채도(Saturation)가&amp;nbsp;섞여&amp;nbsp;있어서,&amp;nbsp;각&amp;nbsp;채널을&amp;nbsp;독립적으로&amp;nbsp;평활화하면&amp;nbsp;원래&amp;nbsp;색상&amp;nbsp;관계가&amp;nbsp;깨져버리기&amp;nbsp;때문 &lt;br /&gt;-&amp;nbsp;먼저&amp;nbsp;RGB로&amp;nbsp;받은&amp;nbsp;이미지를&amp;nbsp;HSV&amp;nbsp;또는&amp;nbsp;YCrCb&amp;nbsp;형태의&amp;nbsp;이미지로&amp;nbsp;변경한&amp;nbsp;다음에&amp;nbsp;밝기값(V(Value))&amp;nbsp;채널에&amp;nbsp;해당하는&amp;nbsp;V&amp;nbsp;또는&amp;nbsp;Y&amp;nbsp;채널에&amp;nbsp;대해서만&amp;nbsp;히스토그램&amp;nbsp;평활화를&amp;nbsp;적용해야&amp;nbsp;색을&amp;nbsp;변경하지&amp;nbsp;않고&amp;nbsp;선명하게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;HSV의&amp;nbsp;V만&amp;nbsp;평활화&amp;nbsp;:&amp;nbsp;색상&amp;nbsp;유지,&amp;nbsp;명도만&amp;nbsp;개선 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;YCrCb의&amp;nbsp;Y만&amp;nbsp;평활화&amp;nbsp;:&amp;nbsp;방송용&amp;nbsp;영상에&amp;nbsp;적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/OXhes/btsNBcsFWNc/AplnKXyQyjpuY2wp4aiVK1/26_%ED%9E%88%EC%8A%A4%ED%86%A0%EA%B7%B8%EB%9E%A8%ED%8F%89%ED%99%9C%ED%99%94%EB%B0%8F%EB%8C%80%EB%B9%84%EC%A1%B0%EC%A0%95.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;26_히스토그램평활화및대비조정.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.52MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/QD35Z/btsNBLu1qA4/nNVbUVUItiw5IkLceC4WB1/32_%EC%9D%B4%EB%AF%B8%EC%A7%80%EC%9E%90%EB%A5%B4%EA%B8%B0.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;32_이미지자르기.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.37MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bIiW7b/btsNDTSm7wi/cIcGAV1qcac1xxDiwNiA9k/33_%EB%8C%80%EC%B9%AD%EB%B3%80%ED%99%98.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;33_대칭변환.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.30MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bUwD3U/btsNDFfOiQE/eQdf9H4PRsuKoWDAQ3LChk/34_%ED%9A%8C%EC%A0%84.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;34_회전.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.42MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어핀 변환(Affine Transform)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;평행&amp;nbsp;이동,&amp;nbsp;확대&amp;nbsp;및&amp;nbsp;축소,&amp;nbsp;회전,&amp;nbsp;스케일&amp;nbsp;변경,&amp;nbsp;뒤틀기&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;방식으로&amp;nbsp;변환할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해주는&amp;nbsp;기법.&amp;nbsp; &lt;br /&gt;-&amp;nbsp;이&amp;nbsp;과정에서&amp;nbsp;이미지의&amp;nbsp;병렬성은&amp;nbsp;유지되지만,&amp;nbsp;각도와&amp;nbsp;크기는&amp;nbsp;변할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;영상에&amp;nbsp;어파인&amp;nbsp;변환을&amp;nbsp;적용할&amp;nbsp;경우&amp;nbsp;직선은&amp;nbsp;그대로&amp;nbsp;직선으로&amp;nbsp;나타나고, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;직선&amp;nbsp;간의&amp;nbsp;길이&amp;nbsp;비율과&amp;nbsp;평행&amp;nbsp;관계가&amp;nbsp;그대로&amp;nbsp;유지된다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;직사각형&amp;nbsp;형태의&amp;nbsp;영상은&amp;nbsp;어파인&amp;nbsp;변환에&amp;nbsp;의해&amp;nbsp;평행사변형에&amp;nbsp;해당하는&amp;nbsp;모습으로&amp;nbsp;변경된다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;영상을&amp;nbsp;구성하는&amp;nbsp;픽셀의&amp;nbsp;배치&amp;nbsp;구조를&amp;nbsp;변경함으로써&amp;nbsp;전체&amp;nbsp;영상의&amp;nbsp;모양을&amp;nbsp;바꾸는&amp;nbsp;작업&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;1.&amp;nbsp;어파인&amp;nbsp;변환&amp;nbsp;행렬&amp;nbsp;구하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw6C8W/btsNDt0MkBH/aMDkiap0HwE3lOU1uYjzGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw6C8W/btsNDt0MkBH/aMDkiap0HwE3lOU1uYjzGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw6C8W/btsNDt0MkBH/aMDkiap0HwE3lOU1uYjzGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw6C8W%2FbtsNDt0MkBH%2FaMDkiap0HwE3lOU1uYjzGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;147&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`martix&amp;nbsp;=&amp;nbsp;cv2.getAffineTransform(pts1,&amp;nbsp;pts2)` &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;pts1:&amp;nbsp;변환&amp;nbsp;전&amp;nbsp;영상의&amp;nbsp;좌표&amp;nbsp;3개,&amp;nbsp;3&amp;nbsp;x&amp;nbsp;2&amp;nbsp;배열 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;pts2:&amp;nbsp;변환&amp;nbsp;후&amp;nbsp;영상의&amp;nbsp;좌표&amp;nbsp;3개,&amp;nbsp;3&amp;nbsp;x&amp;nbsp;2&amp;nbsp;배열 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;matrix:&amp;nbsp;변환&amp;nbsp;행렬&amp;nbsp;반환,&amp;nbsp;2&amp;nbsp;x&amp;nbsp;3&amp;nbsp;행렬&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;어파인&amp;nbsp;변환하기&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;warpAffine()&amp;nbsp;:&amp;nbsp;src&amp;nbsp;영상을&amp;nbsp;어파인&amp;nbsp;변환하여&amp;nbsp;dst&amp;nbsp;영상을&amp;nbsp;생성하는&amp;nbsp;함수&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`cv2.warpAffine(src,&amp;nbsp;M,&amp;nbsp;dsize,&amp;nbsp;dst=None,&amp;nbsp;flags=None,&amp;nbsp;borderMode=None,&amp;nbsp;borderValue=None)&amp;nbsp;-&amp;gt;&amp;nbsp;dst`&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;src:&amp;nbsp;입력&amp;nbsp;영상&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;M:&amp;nbsp;2x3&amp;nbsp;어파인&amp;nbsp;변환&amp;nbsp;행렬.&amp;nbsp;실수형.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;dsize:&amp;nbsp;결과&amp;nbsp;영상&amp;nbsp;크기.&amp;nbsp;(w,&amp;nbsp;h)&amp;nbsp;튜플.&amp;nbsp;(0,&amp;nbsp;0)이면&amp;nbsp;src와&amp;nbsp;같은&amp;nbsp;크기로&amp;nbsp;설정.&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;dst:&amp;nbsp;출력&amp;nbsp;영상&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;flags:&amp;nbsp;보간법.&amp;nbsp;기본값은&amp;nbsp;cv2.INTER_LINEAR.&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;borderMode:&amp;nbsp;가장자리&amp;nbsp;픽셀&amp;nbsp;확장&amp;nbsp;방식.&amp;nbsp;기본값은&amp;nbsp;cv2.BORDER_CONSTANT.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;bull;&amp;nbsp;borderValue:&amp;nbsp;cv2.BORDER_CONSTANT일&amp;nbsp;때&amp;nbsp;사용할&amp;nbsp;상수&amp;nbsp;값.&amp;nbsp;기본값은&amp;nbsp;0(검정색).&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bB2APN/btsNB9WGjrF/pPgzlBYKCMDhyKMwH6cxH1/35_%EC%96%B4%ED%8C%8C%EC%9D%B8%EB%B3%80%ED%99%98.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;35_어파인변환.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.03MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원근 변환(Perspective Transform) : 원근 이미지 &amp;harr; 평면 이미지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트폰으로 문서를 찍으면 주변이 삐둘거리거나 사다리꼴형으로 되는데 이런 이미지를 직사각형으로 펼치는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://bkshin.tistory.com/entry/OpenCV-14-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%92%A4%ED%8B%80%EA%B8%B0%EC%96%B4%ED%95%80-%EB%B3%80%ED%99%98-%EC%9B%90%EA%B7%BC-%EB%B3%80%ED%99%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bkshin.tistory.com/entry/OpenCV-14-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%92%A4%ED%8B%80%EA%B8%B0%EC%96%B4%ED%95%80-%EB%B3%80%ED%99%98-%EC%9B%90%EA%B7%BC-%EB%B3%80%ED%99%98&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원근 변환은 이미지를 3차원으로 변환 - 원근법의 원리를 적용해 변환&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciZ9GM/btsNBF9mNBQ/EdJoqapzCOWT0P5PGeBlkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciZ9GM/btsNBF9mNBQ/EdJoqapzCOWT0P5PGeBlkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciZ9GM/btsNBF9mNBQ/EdJoqapzCOWT0P5PGeBlkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciZ9GM%2FbtsNBF9mNBQ%2FEdJoqapzCOWT0P5PGeBlkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;524&quot; height=&quot;138&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;mtrx&amp;nbsp;=&amp;nbsp;cv2.getPerspectiveTransform(pts1,&amp;nbsp;pts2) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;pts1:&amp;nbsp;변환&amp;nbsp;이전&amp;nbsp;영상의&amp;nbsp;좌표&amp;nbsp;4개,&amp;nbsp;4&amp;nbsp;x&amp;nbsp;2&amp;nbsp;배열 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;pts2:&amp;nbsp;변환&amp;nbsp;이후&amp;nbsp;영상의&amp;nbsp;좌표&amp;nbsp;4개,&amp;nbsp;4&amp;nbsp;x&amp;nbsp;2&amp;nbsp;배열 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;mtrx:&amp;nbsp;변환행렬&amp;nbsp;반환,&amp;nbsp;3&amp;nbsp;x&amp;nbsp;3&amp;nbsp;행렬 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;-&amp;nbsp;cv2.warpPerspective()&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bQIcBO/btsNDsHzXnI/YWLuX2GcwS9x2xLKLvjkk0/36_%EC%9B%90%EA%B7%BC%EB%B3%80%ED%99%98.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;36_원근변환.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.04MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 필터링 및 이미지 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블러링, 샤프닝, 에지 검출, 컨투어 검출 및 외곽선 그리기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bk2LNu/btsNCqcXfou/hNd8vUm2O5SnKoWnpZ84Jk/41_%EB%B8%94%EB%9F%AC%EB%A7%81.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;41_블러링.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징 추출 및 고급 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SIFT, HOG, Haar&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/0Dslq/btsNDx922r4/n0vk3vOXh00KEDxIT0r76k/051_SIFT.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;051_SIFT.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/494</guid>
      <comments>https://hotari.tistory.com/494#entry494comment</comments>
      <pubDate>Mon, 28 Apr 2025 16:53:51 +0900</pubDate>
    </item>
    <item>
      <title>10일차</title>
      <link>https://hotari.tistory.com/493</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.04.25&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병가&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/493</guid>
      <comments>https://hotari.tistory.com/493#entry493comment</comments>
      <pubDate>Mon, 28 Apr 2025 09:11:36 +0900</pubDate>
    </item>
    <item>
      <title>9일차</title>
      <link>https://hotari.tistory.com/492</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.04.24&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bUAqfG/btsNxid7VBr/so2qArIWvlwSteUSMBb4kk/04-32_%EA%B5%B0%EC%A7%91%ED%99%94%EB%AA%A8%EB%8D%B8-Prj1_%EB%A7%88%EC%BC%80%ED%8C%85%EA%B3%A0%EA%B0%9D%EA%B5%B0%EC%A7%91%ED%99%94-%EC%97%B0%EC%8A%B5%ED%8C%8C%EC%9D%BC_0424.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;04-32_군집화모델-Prj1_마케팅고객군집화-연습파일_0424.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.29MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;Windows 에서 NVIDA GPU 사용하기&lt;/b&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[ 기본사항 ]&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;NVIDIA 드라이버 설치 (또는 업데이트) : 최신 설치&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 교육장 PC에 설치된 NVIDIA 드라이버 : &lt;b&gt;GeForce RTX 4060&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nvidia.co.kr/Download/index.aspx?lang=kr&quot;&gt;https://www.nvidia.co.kr/Download/index.aspx?lang=kr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5qEnq/btsNxXHhNcO/UY8MyUdAWIfJQF1LKCsic1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5qEnq/btsNxXHhNcO/UY8MyUdAWIfJQF1LKCsic1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5qEnq/btsNxXHhNcO/UY8MyUdAWIfJQF1LKCsic1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5qEnq%2FbtsNxXHhNcO%2FUY8MyUdAWIfJQF1LKCsic1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;320&quot; height=&quot;298&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czrdox/btsNwcNiOIW/8Tw7GCVimIb19WidRlVY21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czrdox/btsNwcNiOIW/8Tw7GCVimIb19WidRlVY21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czrdox/btsNwcNiOIW/8Tw7GCVimIb19WidRlVY21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczrdox%2FbtsNwcNiOIW%2F8Tw7GCVimIb19WidRlVY21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;272&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설치 확인 : cmd 에서 nvidia-smi 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mZLzD/btsNwsPSlnS/nxfNdVTalrcZZ14Zns9he0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mZLzD/btsNwsPSlnS/nxfNdVTalrcZZ14Zns9he0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mZLzD/btsNwsPSlnS/nxfNdVTalrcZZ14Zns9he0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmZLzD%2FbtsNwsPSlnS%2FnxfNdVTalrcZZ14Zns9he0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;471&quot; height=&quot;511&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 프레임워크 Timeline&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mQIfc/btsNwuGX452/kzqNHoFPAdmFoJFe9kgqA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mQIfc/btsNwuGX452/kzqNHoFPAdmFoJFe9kgqA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mQIfc/btsNwuGX452/kzqNHoFPAdmFoJFe9kgqA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmQIfc%2FbtsNwuGX452%2FkzqNHoFPAdmFoJFe9kgqA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;369&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 프레임워크 비교&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k8rVp/btsNwedhsU5/rfMfpA40W3Bexl4kqEWkU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k8rVp/btsNwedhsU5/rfMfpA40W3Bexl4kqEWkU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k8rVp/btsNwedhsU5/rfMfpA40W3Bexl4kqEWkU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk8rVp%2FbtsNwedhsU5%2FrfMfpA40W3Bexl4kqEWkU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;366&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Keras&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZSTcV/btsNwpZXdYo/3Ak1XrrhTT93mKF6IcqYDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZSTcV/btsNwpZXdYo/3Ak1XrrhTT93mKF6IcqYDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZSTcV/btsNwpZXdYo/3Ak1XrrhTT93mKF6IcqYDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZSTcV%2FbtsNwpZXdYo%2F3Ak1XrrhTT93mKF6IcqYDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;407&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Keras를 이용하여 딥러닝 학습하기 프로세스&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgTT5m/btsNvdSBs4K/ISkVwThzEEnKs15MeI6Ev0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgTT5m/btsNvdSBs4K/ISkVwThzEEnKs15MeI6Ev0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgTT5m/btsNvdSBs4K/ISkVwThzEEnKs15MeI6Ev0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgTT5m%2FbtsNvdSBs4K%2FISkVwThzEEnKs15MeI6Ev0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;770&quot; height=&quot;414&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qBOuM/btsNwSAy6hY/9IEbNZCu8vs25RAgX9JkGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qBOuM/btsNwSAy6hY/9IEbNZCu8vs25RAgX9JkGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qBOuM/btsNwSAy6hY/9IEbNZCu8vs25RAgX9JkGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqBOuM%2FbtsNwSAy6hY%2F9IEbNZCu8vs25RAgX9JkGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;833&quot; height=&quot;452&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MLP의 한계&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xr59f/btsNw3BvhzO/gvovDXtccPP3kzjmDYIbK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xr59f/btsNw3BvhzO/gvovDXtccPP3kzjmDYIbK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xr59f/btsNw3BvhzO/gvovDXtccPP3kzjmDYIbK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxr59f%2FbtsNw3BvhzO%2FgvovDXtccPP3kzjmDYIbK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;859&quot; height=&quot;439&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MLP의 한계 극복&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1980 ~ 1990년대 후반까지 MLP의 한계를 극복하지 못했지만, 이후 딥러닝 연구와 함께 다음의 혁신적인 기술들로 해결됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO9FjJ/btsNygGFvoU/IJuE0mmXYaq4IpTKH0fr0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO9FjJ/btsNygGFvoU/IJuE0mmXYaq4IpTKH0fr0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO9FjJ/btsNygGFvoU/IJuE0mmXYaq4IpTKH0fr0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO9FjJ%2FbtsNygGFvoU%2FIJuE0mmXYaq4IpTKH0fr0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;346&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 활성화함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 활성화함수(activation function) : 생물학전 뉴런에서 입력 신호가 일정 크기 이상일 때만 신호를 전달하는 메커니즘을 모방한 함수&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bexjDI/btsNwYAsIlY/l0eIVk9SlxybM7IhMXGoaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bexjDI/btsNwYAsIlY/l0eIVk9SlxybM7IhMXGoaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bexjDI/btsNwYAsIlY/l0eIVk9SlxybM7IhMXGoaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbexjDI%2FbtsNwYAsIlY%2Fl0eIVk9SlxybM7IhMXGoaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;801&quot; height=&quot;215&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 -&amp;nbsp; 선형변환&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOXzwI/btsNw7jBMnp/7fnvNFKfkBc73VfEKOKUU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOXzwI/btsNw7jBMnp/7fnvNFKfkBc73VfEKOKUU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOXzwI/btsNw7jBMnp/7fnvNFKfkBc73VfEKOKUU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOXzwI%2FbtsNw7jBMnp%2F7fnvNFKfkBc73VfEKOKUU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;346&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 비선형변환&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqqeGf/btsNuIk5Ofh/Pq0OE4iUWotJoAPk77qtm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqqeGf/btsNuIk5Ofh/Pq0OE4iUWotJoAPk77qtm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqqeGf/btsNuIk5Ofh/Pq0OE4iUWotJoAPk77qtm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqqeGf%2FbtsNuIk5Ofh%2FPq0OE4iUWotJoAPk77qtm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;731&quot; height=&quot;350&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동&amp;nbsp; 원리 - 비용함수 업데이트 &amp;amp;학습률&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2otC1/btsNw6544Wx/aMHGkdeUwIHunjfPFOwrz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2otC1/btsNw6544Wx/aMHGkdeUwIHunjfPFOwrz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2otC1/btsNw6544Wx/aMHGkdeUwIHunjfPFOwrz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2otC1%2FbtsNw6544Wx%2FaMHGkdeUwIHunjfPFOwrz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;296&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 옵티마이저&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;359&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwxmkv/btsNyiLeyhe/TPjcKgTl5oYHjyr0o3M3tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwxmkv/btsNyiLeyhe/TPjcKgTl5oYHjyr0o3M3tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwxmkv/btsNyiLeyhe/TPjcKgTl5oYHjyr0o3M3tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwxmkv%2FbtsNyiLeyhe%2FTPjcKgTl5oYHjyr0o3M3tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;955&quot; height=&quot;359&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;359&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 순전파 / 역전파&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJQH7l/btsNwcftsnr/RATa7W4kREc8pcxZmTJKdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJQH7l/btsNwcftsnr/RATa7W4kREc8pcxZmTJKdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJQH7l/btsNwcftsnr/RATa7W4kREc8pcxZmTJKdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJQH7l%2FbtsNwcftsnr%2FRATa7W4kREc8pcxZmTJKdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;356&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 역전파에 체인룰 적용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0HbF9/btsNxS0j9mV/HhPUMSGcWmMNzaYiK5RCH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0HbF9/btsNxS0j9mV/HhPUMSGcWmMNzaYiK5RCH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0HbF9/btsNxS0j9mV/HhPUMSGcWmMNzaYiK5RCH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0HbF9%2FbtsNxS0j9mV%2FHhPUMSGcWmMNzaYiK5RCH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;394&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 작동 원리 - 분류 : 손실함수&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z3r7b/btsNx0RCy25/aMNLxuy38tJhiGygX7T760/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z3r7b/btsNx0RCy25/aMNLxuy38tJhiGygX7T760/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z3r7b/btsNx0RCy25/aMNLxuy38tJhiGygX7T760/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz3r7b%2FbtsNx0RCy25%2FaMNLxuy38tJhiGygX7T760%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;363&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터셋 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 훈련데이터셋, 테스트 데이터셋, 검증데이터셋&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzaN4/btsNwplolFe/sKCZA1MeURoD2CXdS5ma5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzaN4/btsNwplolFe/sKCZA1MeURoD2CXdS5ma5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzaN4/btsNwplolFe/sKCZA1MeURoD2CXdS5ma5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxzaN4%2FbtsNwplolFe%2FsKCZA1MeURoD2CXdS5ma5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;279&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://playground.tensorflow.org/#activation=tanh&amp;amp;batchSize=10&amp;amp;dataset=xor&amp;amp;regDataset=reg-plane&amp;amp;learningRate=0.003&amp;amp;regularizationRate=0&amp;amp;noise=0&amp;amp;networkShape=4,4&amp;amp;seed=0.24628&amp;amp;showTestData=false&amp;amp;discretize=false&amp;amp;percTrainData=50&amp;amp;x=true&amp;amp;y=true&amp;amp;xTimesY=false&amp;amp;xSquared=false&amp;amp;ySquared=false&amp;amp;cosX=false&amp;amp;sinX=false&amp;amp;cosY=false&amp;amp;sinY=false&amp;amp;collectStats=false&amp;amp;problem=classification&amp;amp;initZero=false&amp;amp;hideText=false&quot;&gt;A Neural Network Playground&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[ 딥러닝 프레임워크에서 gpu 사용하기 ]&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.Tensorflow 및 필요한 라이브러리 설치하기&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;anaconda prompt 에서 라이브러리 설치&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tensorflow.org/install/pip?hl=ko&quot;&gt;https://www.tensorflow.org/install/pip?hl=ko&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.notion.so/tensorflow-gpu-1-1d3ef6fa7801810db565c71a950fa3e6?pvs=21&quot;&gt;tensorflow - gpu 만나게 하기 (1)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Anaconda prompt로 새로운 가상환경을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1745463736529&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n (가상환경의 이름) python=3.10
예) conda create -n tf-gpu python=3.10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 새로 만든 가상환경을 Activate한다.&lt;/p&gt;
&lt;pre id=&quot;code_1745463782261&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda activate tf-gpu&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 가상환경에서 다음을 설치한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;pip install &quot;numpy&amp;lt;2.0&quot; 

conda install -c conda-forge cudatoolkit=11.8 cudnn=8.9.7
pip install tensorflow-gpu==2.10&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;( or &lt;b&gt;conda-forge&lt;/b&gt;와 &lt;b&gt;defaults&lt;/b&gt; 채널에서는 cudatoolkit=12.8이 제공되지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 커널 생성 : 주피터 노트북 파일 사용할 경우&lt;/p&gt;
&lt;pre id=&quot;code_1745463905743&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install ipykernel&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 주피터 노트북 프로그램에서 커널 이름 보이게 하기&lt;/p&gt;
&lt;pre id=&quot;code_1745463912579&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m ipykernel install --user --name=tf-gpu&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 주피터 노트북 셀에서 코드를 돌려보고 확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1745463930625&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마지막 명령어를 쳤을 때 아래와 같이 나오면, 70퍼센트 성공왜냐하면 이 상태로는 주피터 노트북에서 실행이 안 되기 때문이다&amp;hellip;&lt;/li&gt;
&lt;li&gt;새로운 주피터 노트북 ipykernel 만들기 오른쪽 상단의 커널 버튼을 누르고 가상환경의 이름을 선택한다&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgB6Ld/btsNxmASQME/BAXzZHMBVZ3u5yhd9hWAcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgB6Ld/btsNxmASQME/BAXzZHMBVZ3u5yhd9hWAcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgB6Ld/btsNxmASQME/BAXzZHMBVZ3u5yhd9hWAcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgB6Ld%2FbtsNxmASQME%2FBAXzZHMBVZ3u5yhd9hWAcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;323&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 해도 문제 발생 시&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;추가로 tensorflow-gpu 2.10.0, CUDA 12, 11 를 모두 설치했음에도 GPU 가 정상적으로 로드 되지 않았던 경험이 있었습니다. 
해당 현상은 환경 변수에 &quot;C:\\tools\\cuda\\bin&quot;를 추가하여 해결한 정보를 공유드립니다.
&amp;gt; 출처: &amp;lt;https://www.tensorflow.org/install/gpu?hl=ko&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.Pytorch 및 필요한 라이브러리 설치하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Anaconda3 내 설정만으로 PyTorch GPU 환경을 설정하는 방법&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;conda 업데이트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda update -n base -c defaults conda&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;가상환경 생성 (torch-gpu로 생성, 필요하면 이름 변경)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda create -n torch-gpu python=3.10&lt;/li&gt;
&lt;li&gt;conda activate torch-gpu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CUDA 11.8 / CuDNN 8.9.7 설치
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda install -c conda-forge cudatoolkit=11.8 cudnn=8.9.7 ( or &lt;b&gt;conda-forge&lt;/b&gt;와 &lt;b&gt;defaults&lt;/b&gt; 채널에서는 cudatoolkit=12.8이 제공되지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PyTorch 2.3.0 설치
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;커널 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pip install ipykernel&lt;/li&gt;
&lt;li&gt;python -m ipykernel install --user --name=torch-gpu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;설치 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1745464108254&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import torch

print(torch.__version__)
print(torch.cuda.is_available())
print(torch.cuda.current_device())
print(torch.cuda.get_device_name(0))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/c4ehha/btsNxj52z9m/hcFBecD6o5jBu9GvfTtJNK/05-11_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8-DNN%20%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0_%EB%B6%84%EB%A5%98_Tensorflow.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05-11_신경망모델-DNN 알아보기_분류_Tensorflow.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.16MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cscYMk/btsNyepBUDu/Q3ek3xFlEH7i0lQTFcNrBk/05-12_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8-DNN-%ED%9A%8C%EA%B7%80-%EC%A3%BC%ED%83%9D%EA%B0%80%EA%B2%A9%EC%98%88%EC%B8%A1%20-%20%EC%99%84%EC%84%B1%EC%BD%94%EB%93%9C.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05-12_신경망모델-DNN-회귀-주택가격예측 - 완성코드.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.10MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/CGrdf/btsNBbUGRFT/5vE98pkAD0pfNQbzkFFJsK/05-13_%EC%8B%A0%EA%B2%BD%EB%A7%9D%EB%AA%A8%EB%8D%B8-DNN_%EB%B6%84%EB%A5%98%28%EC%9D%B4%EB%AF%B8%EC%A7%80%29-%EC%86%90%EA%B8%80%EC%94%A8%EC%88%AB%EC%9E%90%EB%B6%84%EB%A5%98_Tensorflow-%EC%99%84%EC%84%B1%EC%BD%94%EB%93%9C.ipynb?attach=1&amp;amp;knm=tfile.ipynb&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;05-13_신경망모델-DNN_분류(이미지)-손글씨숫자분류_Tensorflow-완성코드.ipynb&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.42MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>(Telechips) AI 시스템 반도체 SW 개발자 교육/비전과AI머신러닝</category>
      <author>호타리</author>
      <guid isPermaLink="true">https://hotari.tistory.com/492</guid>
      <comments>https://hotari.tistory.com/492#entry492comment</comments>
      <pubDate>Thu, 24 Apr 2025 16:46:07 +0900</pubDate>
    </item>
  </channel>
</rss>