1. 저출산의 문제는 무엇인가?

2. 왜 저출산을 해결하지 못하는가?

3. 해결방법은?

 

 

 

1. 저출산의 문제는 무엇인가?

- 마을 단위가 사라짐 (아버지 시대때만하더라도 마을, 동네가 함께 육아에 동참)   

- 가족 구성원의 감소로 육아의 난이도 증가

-  맞벌이로 인한 육아 난이도 증가

 

2. 왜 저출산을 해결하지 못하는가?

- 인구 초고밀도화로 인한 집값 상승 -  1년에 4천만원씩 모아서 10년을 모아야 구매가능 

- 경쟁심화로 출산 포기

- 정책에 문제가 있음. https://nhuf.molit.go.kr/FP/FP05/FP0502/FP05020401.jsp 합산 7500이라 걍 혼인신고하지말고 혼자서하는게 이득임

 

3. 해결방법은?

- 광역시급 단위에 교육기관 + 기업클러스터화 + 학생들의 무료 기숙사 차려주고, 거기서 취업하면 걍 집주면 애낳고 잘삼

5년정도 기다리긴 해야함

- 서울세 매겨서 1번 정책에 써야함

 

 

해결방법을 못하는 이유는?
- 근데 문제가 한국에 전세라는 아주 기똥찬 제도 때문에 이렇게 하면 한국전체가 망해버림

- 전세대출을 없애야함. 전세제도 자체가 나쁘다고는 생각하지 않음. (전세제도 자체는 월세를 깍는 효과가 있긴 함)

 

 

 

 

엄청난 돈 쏟아가며 저출산 원인 분석하는데 저출산 원인을 분석하는 사람도, 취재하는 사람도, 스크립트를 짠 사람도 다 서울에 살면서 왜 저출산일까요 이러는거 진짜 에휴..

 

 

 

 

 

 

https://fpcv.cs.columbia.edu/ 

1. 성능
아이폰 >>>>>> 갤럭시
최적화는 절대 갤럭시가 따라갈 수 없다.

갤럭시가 아무리 하드웨어 성능이 깡패라도 최적화는 노답

OS 성능도 압도적임.

솔직히 폰으로 게임할거 아니라 나에겐 크게 영향이 없음

2. 연동성

아이폰 >> 갤럭시

맥북 + 아이패드를 쓰는 필자라 연동성은 인정함.
예전에는 진짜 압도적으로 좋았는데 요즘은 갤럭시가 많이 따라와서 딱히 불편함 못느끼고 
IOS 와 안드로이드 + 윈도우 사이의 유틸도 좋아짐

3. 카메라 
아이폰 < 갤럭시
갠적으로 하드웨어적인 성능으로는 갤럭시 압승. 
소프트웨어로는 아이폰이 조금 더 나은 느낌

4. UX
아이폰 <<<<<갤럭시

아이폰3GS, 4,8,13 쓸때마다 UX 핵구리다 생각함
특히 통화 한번 터치하면 전화되는거 좀 없애면 안될까나.

뒤로가기버튼 어디다 팔아먹었지

저장공간 돈 장사... 마이크로SD카드 넣어주면 안되나요~?!

 

5. 유틸

아이폰 <<< 갤럭시

솔직히 내가 아직 갤럭시를 쓰는 이유 중 하나

삼성페이 + 라이브 웰페이퍼(구글지원)

티머니 안되는 애플페이는 별 의미없음

 

총 정리

아이폰 15때 C타입으로 변경되면서 15나 16으로 갈아탈까하다가

갤럭시24 AI 기능에 빠져서 특히 번역이랑 사진+검색기능에 S20FE쓰다가 넘어가버림.
아이폰 16 AI 기능보면서 또 비교하면 재미있을듯

 

https://partnerhelp.netflixstudios.com/hc/ko-kr/articles/360060570713--%EB%8D%B0%EB%93%9C-%ED%94%BD%EC%85%80-%EC%A0%95%EC%9D%98-%EC%88%98%EC%A0%95-%EB%B0%A9%EB%B2%95-%EB%B0%8F-%EB%B0%A9%EC%A7%80-%EB%8C%80%EC%B1%85

https://github.com/AUTOMATIC1111/stable-diffusion-webui

 

GitHub - AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI

Stable Diffusion web UI. Contribute to AUTOMATIC1111/stable-diffusion-webui development by creating an account on GitHub.

github.com





Automatic Installation on Windows

  1. Install Python 3.10.6 (Newer version of Python does not support torch), checking "Add Python to PATH".
  2. Install git.
  3. Download the stable-diffusion-webui repository, for example by running git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git.
  4. Run webui-user.bat from Windows Explorer as normal, non-administrator, user.

Automatic Installation on Linux

  1. Install the dependencies:
# Debian-based:
sudo apt install wget git python3 python3-venv libgl1 libglib2.0-0
# Red Hat-based:
sudo dnf install wget git python3 gperftools-libs libglvnd-glx 
# openSUSE-based:
sudo zypper install wget git python3 libtcmalloc4 libglvnd
# Arch-based:
sudo pacman -S wget git python3
 
  1. Navigate to the directory you would like the webui to be installed and execute the following command:
wget -q https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh
 
  1. Run webui.sh.
  2. Check webui-user.sh for options.

 

 

필수 익스텐션

 

https://rupicat.com/entry/Stable-Diffusion-Webui-%ED%95%84%EC%88%98-%EC%9C%A0%EC%9A%A9%ED%95%9C-Extensions-%EC%9D%B5%EC%8A%A4%ED%85%90%EC%85%98-%EB%93%A4

https://www.comcbt.com/  문제은행

 


https://www.ihd.or.kr/introducesubject1.do

리눅스 일반 리눅스의 이해 리눅스의 개요, 역사, 철학
리눅스 설치 기본 설치 및 유형, 파티션과 파일 시스템, Boot Manager
기본 명령어 사용자 생성 및 계정 관리, 디렉터리 및 파일, 기타 명령어
리눅스 운영 및 관리 파일 시스템 관련 명령어 권한 및 그룹 설정, 파일 시스템의 관리
Shell 개념 및 종류, 환경 설정
프로세스 관리 개념 및 유형, 프로세스 Utility
에디터 에디터의 종류, 에디터 활용
소프트웨어 설치 개념 및 사용법, 소프트웨어 설치 및 삭제
장치 설정 주변장치 연결 및 설정, 주변장치 활용
리눅스 활용 X 윈도 개념 및 사용법, X 윈도 활용
인터넷 활용 네트워크의 개념, 인터넷 서비스의 종류, 인터넷 서비스의 설정
응용분야 기술동향, 활용기술

 

 

개인적인 공부방법(순공 2시간 10일 공부법)                                                                                                         
3일 3년 기출 먼저 풀어보기 -> 2일 개념정리 -> 2일 3년 기출 ->  2일 개념외우기 -> 시험느낌으로 3년치 CBT돌리기

 

버릴껀 버리자!! 단 기출은 또 나올 수 있으니 반드시 외워서 가자!!

 

 

 

 

리눅스 이해

 

리눅스 설치



기본 명령어

1. 파일 속성 조회 방법 (ls -l)

명령어: ls -l 사용

첫 번째 필드: 파일이나 디렉터리의 허가권 (chmod, umask로 설정 가능)

세 번째 필드: 파일이나 디렉터리의 소유자 (chown로 설정 가능)

네 번째 필드: 파일이나 디렉터리의 소유그룹 (chown, chgrp로 설정 가능)

 

 

* 참고 리눅스 ls 명령어 옵션

-a: 숨겨진 파일도 출력

-l: 자세하게 출력

-s: 파일 크기 순 정렬 (-h와 함께 -sh로 자주 사용)

-h: 파일크기 보기좋게 표시 (-s와 함께 -sh로 자주 사용)

-r: 역순 정렬 (기본은 알파벳순 정렬)

-R: 하위 디렉토리도 출력

-lu: atime(접근 access 시간) 출력 - 기본은 수정시간 mtime 표시

-lc: ctime(파일 저보 변경 change 시간) 출력 - 기본은 수정시간 mtime 표시

 

2. 소유권 관련 명령어 (chown, chgrp)

chown

: 파일과 디렉터리의 사용자 소유권과 소유그룹 변경

: 소유권 변경 시 참조하는 파일 /etc/passwd

: 기본 변경 → chown 변경할사용자명 파일/디렉토리명 (예: chown host a.txt)

: 소유그룹 변경 → chown 변경할사용자명:변경할그룹명 파일/디렉토리명 (예: chown host:grp a.txt)

 

chgrp

: 파일이나 디렉터리의 그룹 소유권 변경

 

3. 허가권 관련 명령어 (chmod, umask)

명령어 ls -l을 사용하여 파일 유형과 허가권을 알 수 있음

파일 유형: d (디렉터리) / - (일반파일) / l (링크파일) / b (블록 디바이스) / c (문자 디바이스)

파일 허가권: 읽기(read-4), 쓰기 (write-2), 실행(execute-1)으로 구성 / 접근 제한은 -

 

 

위 내용을 예로 들면 bench.py 파일의 허가권은

- (일반파일) , rw-(6 읽기 쓰기, 소유자 권한), r--(4 읽기, 소유그룹 권한), r--(4 읽기, 그 외 권한)

0 ---    3 -wx   6 rw-

1 --x     4 r--    7 rwx

2 -w-    5 r-x

 

chmod

: 파일이나 디렉터리의 접근 허가권을 변경하는 명령어

: chmod 소유자권한번호 소유그룹권한번호 그외권한번호 파일및디렉토리명 (예: chmod 744 a.txt

 

umask

: 새로 생성되는 파일이나 디렉터리의 기본 허가권 값 지정

: 파일 기본 권한 666, 디렉터리 기본 권한 777

: 기본 권한 - umask value = defualt permission

: umask 숫자값임. 기본 권한에서 umask 값을 빼야 default permission 값을 알 수 있음

: umask -S 문자값임. 문자값 그대로 권한(default permission) 설정

4. 특수 권한 (SetUID, SetGID, Sticky Bit)

SetUID / SetGID

: 프로세스가 실해되는 동안 해당 프로세스의 소유자(SetUID)/소유그룹(SetGID)의 권한을 임시로 가져오는 기능

: 프로세스가 사용자보다 높은 수준의 접근을 요구할 때 파일 접근 제한 때문에 원활한 기능을 제공할 수 없기 때문에 이러한 문제 해결을 위한 방법

: 사용의 용이성을 위해 부여하나, 보안에 위협적임

: SetUID의 경우 소유자 권한으로 파일 실행시 u+s

: SetGID의 경우 소유 그룹으로 파일 실행 시 g+s

: 만약 유저/그룹 퍼미션 자리에 실행 권한이 있으면 s(정상), 없으면 권한이 비유효하므로 S(비정상)

 

Sticky Bit

: 일반적으로 공용 디렉터리를 사용할 때 Sticky Bit (o+t) 설정

: 유효시 소문자 t, 비유효시 대문자 T

: 공용 디렉터리에는 누구든지 파일 생성이 가능하나, 수정 및 삭제는 root와 소유자만 가능

: 대표적인 공용 디렉터리는 /tmp /var/tmp가 있음

 

5. 디스크 쿼터 (Quota)

파일 시스템마다 사용자나 그룹이 생성할 수 있는 파일의 용량(블록단위) 및 개수(inode 수)를 제한하는 것

사용자별, 파일 시스템별로 동작! 관련 내용은 /etc/fstab에서 디스크 쿼터 관련 설정 확인 가능

그룹 단위로도 용량 제한이 가능하여, 웹 호스팅 서비스 시 유용

 

순서: quotacheck → edquota → quotaon →requota

quotacheck: 파일 시스템의 디스크 사용 상태를 검색. 쿼터 설정을 확인하여 쿼터가 존재할 경우에는 생성 (aquota.user, aquota.group: 사용자, 그룹의 쿼터 관련 정보 기록)

edquota: vi 편집기를 이용하여 사용자나 그룹에 디스크 사용량 할당

setquota: 편집기나 아닌 명령행에서 바로 사용자나 그룹에 디스크 사용량 할당

quotaon/off: 쿼터 서비스를 활성화/비활성화

requota: 파일 시스템 단위로 쿼터 설정 표기 확인

출처: https://thinking-developer.tistory.com/51 [생각하는 개발자:티스토리]

 

 


 

 

 

파일 시스템 관련 명령어

1. 파일 시스템이란

: 운영체제가 파일을 시스템의 디스크상에 구성하는 방식

: 컴퓨터에서 파일이나 자료를 쉽게 발견 및 접근할 수 있도록 보관 또는 조직하는 체제: 

: 하드디스크나 CD-ROM과 같은 물리적 저장소 관리

2. 리눅스 전용 디스크 기반 파일 시스템 (EXT 시리즈)

파일 시스템 설명
EXT - 리눅스 초기에 사용되던 시스템
- 호환성 없음
- EXT2의 원형
- 2GB의 데이터와 파일명 255자까지 지정 가능
EXT2 - 고용량 디스크 사용을 염두하고 설계된 파일 시스템
- 호환과 업그레이드가 쉬움
- 4TB 파일 크기까지 지원
- 설정 방법) mke2fs - t ext2
EXT3 - 리눅스의 대표적인 저널링을 지원하도록 확장된 파일 시스템
- ACL (Access Control List)를 통한 접근 제어 지원
- 16TB의 파일 크기까지 지원
- 설정 방법 1) mke2fs -j
- 설정 방법 2) mke2fs -t ext3 
EXT4 - 파일에 디스크 할당 시 물리적으로 연속적인 블록을 할당
- 64비트 기억 공간 제한을 없앰
- 16TB 파일 크기까지 지원
- 설정 방법 1) mke2fs -t ext4

 

3. 저널링 파일 시스템 (JFS, XFS, ReiserFS, EXT3)

파일 시스템 설명
JFS - Journaling File System의 약자
- IBM사의 독자적인 저널링 파일 시스템
- GPL로 공개하여 현재 리눅스용으로 개발
XFS - eXetended File System의 약자
- 고성능 저널링 시스템 (SGI 제작)
- 64bit 주소 지원 및 확장성 있는 자료 구조와 알고리즘 사용
- 데이터 읽기/쓰기 트랜잭션으로 성능 저하를 최소화
- 64bit 파일 시스템으로 8EB까지의 대용량 파일도 다룰 수 있음
ReiserFS - 독일의 한스 라이저가 개발한 파일 시스템
- 모든 파일 객체들을 B트리에 저장, 간결한 색인화된 디렉터리 지원

 

4. 네트워크 파일 시스템

파일 시스템 설명
SMB - Server Message Block
- 옵션) smbfs
- 삼바 파일 시스템을 마운트 지정
- 윈도우 계열 OS 환경에서 사용되는 파일/프린터 공유 프로토콜
- 리눅스, 유닉스 계절 OS와 윈도우 OS와의 자료 및 하드웨어 공유 (다른 OS와 자료 및 HW 공유 용이)
CIFS - Common Internet File System
- SMB를 확장한 파일 시스템
- SMB를 기초로 응용하여 라우터를 뛰어넘어 연결할 수 있는 프로토콜
NFS - Network File System
- 옵션) nfs
- 동일 OS간 RPC를 기반으로 파일 공유시 사용 권장
- 파일 공유 및 파일 서버로 사용하고, 공유된 영역을 마운트할 때 지정
- HW, OS 또는 네트워크 구조가 달라도 공유 가능
- NFS 서버의 특정 디렉터리를 마운트하여 사용 가능
EXT4 - 파일에 디스크 할당 시 물리적으로 연속적인 블록을 할당
- 64비트 기억 공간 제한을 없앰
- 16TB 파일 크기까지 지원
- 설정 방법 1) mke2fs-t ext4

 

5. 기타 파일 시스템

파일 시스템 설명
FAT - Windows NT가 지원하는 파일 시스템 중 가장 간단한 시스텥ㅁ
- 옵션) vfat
- FAT로 포맷된 디스크는 클러스터 단위로 할당하며, 클러스터 크기는 볼륨 크기에 따라 결정
- 읽기 전용, 숨김, 시스템 및 보관 파일 특성만 지원
- 삼바 파일 시스템을 마운트 지정
VFAT - Virtual FAT
- FAT 파일 시스템이 확장된 것으로 FAT보다 제한이 적음
- 파일 이름도 최고 255자까지 만들 수 있음 (= EXT)
- 공백이나 여러 개의 구두점도 포함
FAT32 - SMB를 확장한 파일 시스템
- 다중 부팅 가능
- 파일 크기 최대 4GB, 파티션 크기 최대 32GB
NTFS - 윈도우에서 사용하는 파일 시스템
- 옵션) ntfs
- 안정성이 뛰어나고 대용량 파일도 저장
-  파일 크기 및 볼륨은 이론상 최대 16EB이지만, 실질적으로 2TB가 한계
ISO 9660 - CD-ROM의 표준 파일 시스템
- 옵션) loop
- 1988년에 재정된 표준
UDF - Universal Disk Format의 약자로 최신 파일 시스템 형식
- 광학 매체용 파일 시스템 표준
- ISO 9660 파일 시스템을 대체하기 위한 것으로 대부분 DVD에서 사용
HPFS OS/2 운영체제를 위해 만들어진 파일 시스템

 

6. 관련 명령어

mount & umount

: mount [option] [device] [directory]

: 마운트는 특정 디바이스를 특정 디렉터리처럼 사용하기 위해 장치와 디렉터리를 연결

: 리눅스는 PnP (Plug and Play)를 지원하지만, 지원하는 HW가 많지 않으므로 시스템 부팅 후 수동으로 마운트한 뒤 사용을 끝낸 뒤에는 직접 언마운트 시켜야 함

: /etc/mtab에 현재 마운트된 블록 시스템 정보 표시

: 옵션 정보

  • -a: /etc/fstab에 명시된 파일 시스템 마운트 시 사용
  • -t 타입명: 파일 시스템 유형 지정 시 사용
  • -o 항목명: 추가 설정 및 다수 옵션 지정시 사용
    항목명 ro: 읽기 전용
    항목명 rw: 읽기 및 쓰기, 기본 지정
    항목명 remount: 재마운트
    항목명 loop: iso 9660 마운트 시 사용
    항목명 noatime: atime 변경 제어로 작업 성능 향상

eject

: 이동식 보조기억장치등과 같은 미디어를 해제하고 장치를 제거하는 명령어

: 이전에 umount (자동) 필수 수행!

 

fdisk

: 새로운 파티션의 생성, 기존 파티션의 삭제, 파티션의 타입 결정 등의 작업 수행

: 한 번에 한 디스크에 대해서만 작업 수행
: 명령어 저장 위치 /sbin/fdisk: 디스크 파티션에 부여된 UUID 값 확인시 'blkid' 명령어 사용

: 옵션 정보

  • -l: 현재 디스크 및 파티션 조회
  • -n: 신규 파티션 추가
  • -t: 파티션 종류 변경
    SWAP - 82, Linux - 83, LVM - 8e, RAID - fd, FAT32 - b
  • -p: 파티션 테이블로 설정 보기
  • -m: 메뉴 보기
  • -a: 부트 가능 플래그로 변경
  • -d: 뒷번호부터 차례대로 파티션 삭제
  • -w: 파티션 설정 저장

mkfs

: 리눅스 파일 시스템 생성

: fdisk로 하드디스크 파티션을 나눈 후 해당 파티션에 맞는 파일 시스템 생성

 

mke2fs

: ext2, ext3, ext4 타입의 리눅스 파일 시스템을 생성하는 명령어

 

fsck

: 파일 시스템의 무결성 점검 및 대화식으로 복구

: 결함이 있는 파일에 대한 정보가 저장되는 디렉토리 /etc/lost+found를 사용하여 점검 및 복구

 

e2fsck

: ext2, ext3, ext4 타입의 리눅스 파일 시스템을 복구하는 명령어

 

du

: Disk Usage 약자로 디렉터리별 디스크 사용량 확인

 

df

: 시스템에 마운트된 하드 디스크/파티션의 남은 용량을 확인할 때 사용하는 명령어

: 기본적으로 1024Byte 블록 단위로 출력

: 옵션 -h 보기편하게, -T 타입 출력

출처: https://thinking-developer.tistory.com/52 [생각하는 개발자:티스토리]


 

 

 

 

Shell  (https://thinking-developer.tistory.com/53)

1. 셸이란

 

이미지 출처: https://c11.kr/kfky

 

: 사용자와 커널 사이의 명령어 해석기

: 로그인할 때 실행되어 사용자별로 사용 환경 설정을 가능하게 함

: 강력한 스크립트 언어

: 입출력 방향 재지정과 파이프 ( | ) 기능을 제공

: 포어/백그라운드 프로세스 실행

2. 종류

: 본셸($) 계열와 C셸(%) 계열로 나뉨

: 대부분의 셸은 본셸 계열의 기능을 포함하여 확대 발전한 혀태

: C셸은 본셸의 모든 기능과 명령어 히스토리 별명, 작업 제어 기능을 추가로 가지고 있음

: 아래의 표는 왼쪽에서 오른쪽으로 갈수록 나중에 나온 것임

: dash - POSIX와 호환되는 /bin/sh를 작계 구현한 셸로, 빠른 작업 수행이 특징이지만 히스토리 등 명령 지원 X

본셸 (bourne shell) C셸 (csh) tcsh ksh bash
- 스티브 본 개발
- 최초의 셸
- 빌 조이 개발
- 히스토리 기능 제공
- 별칭(alias) 기능 제공
- csh를 확장한 것
- 명령어 행 자동 완성
- 명령어 행 편집 기능
- 데이비드 콘 개발
- csh를 포함하여 본셸과도 호환
- 브라이언 폭스 개발
- GNU 프로젝트에서 개발
- 히스토리, 자동완성 등 앞서 개발한 기능 대부분 제공
- 리눅스에서 가장 多 사용

: bash 셸의 주요 기능

1) History 기능

  • 일정 개수 이상 사용했던 명령어를 bash_history에 저장해두고 다시 불러서 사용할 수 있게 하는 기능
  • 대부분의 셸은 이전에 입력했던 명령어를 반복하거나 약간 변형하여 다시 사용할 수 있도록 하는 기능

2) alias 기능

  • 자주 사용하는 명령어를 특정 문자로 입력해두고 간편하게 사용할 수 있게 하는 기능
  • alias 별칭='명령어'
  • 별칭 해제 명령어는 unalias
  • 별칭 목록 확인 시 명령어는 alias

3. 셸 확인 및 변경

로그인 셸 확인

: 파일 /etc/shell 에서 사용할 수 있는 셸들을 확인할 수 있음 (ls -l /etc/shell)

: 파일 /etc/passwd 파일에서 계정마다 할당된 셸을 확인할 수 있음

: 명령어 echo $SHELL은 현재 로그인한 사용자가 사용하고 있는 셸을 확인할 수 있음

: 로그아웃 시 실행할 명령은 bash-logout에 입력

 

셸 변경

: 로그인 셸 변경은 반영구적인 셸 변경 방법으로 관리자가 셸 변경 후 다음 변경을 하기 전까지 지정된 셸 사용

: 명령어 chsh - 일반 사용자 환경에서 셸 변경 시 사용

: 명령어 usermod - 관리자 환경에서 지정된 계정자의 정보를 변경할 때 사용하는 명령어

4. 환경 변수와 셸 변수

환경 변수 (전역 변수, env)

: 전체 셸에서 사용 가능한 전역 변수

: 서브 셸에 기능 상속 가능

: 환경 변수 확인 명령 env (printenv)

: 대표적인 환경 변수의 예

  • $SHELL: 현재 사용자가 사용중인 셸
  • $TERM: 터미널 종류의 이름
  • $LANG: 기본 자원 언어
  • $PS1: SHELL 프롬프트 선언 (기본)
  • $PS2: 2차 SHELL 프롬프트 선언 (보조)

    1. LOGIN : 로그인 세션을 나타내는 쉘 환경변수
    2. USER : 현재 사용자 이름을 나타내는 환경변수
    3. SHELL : 현재 사용중인 쉘경로를 나타내는 환경변수
    4. BASH : bash 쉘에 대한 정보를 나타내는 환경변수

셸 변수 (지역 변수, set)

: 현재 로그인 셸에서만 사용 가능한 지역 변수

: 서브 셸에 기능 상속 불가능

5. 환경 설정 파일

: 셸 시작 시 자동으로 실행되는 고유의 시작 파일이 있음. 이 파일은 사용자 운영 환경을 결정

: 배시셸의 시작 파일

  • /etc/profile: 전체 환경 설정
  • /etc/bashrc: 전체 변수 설정
  • ~/.bash_profile: 사용자별 환경 설정
  • ~/.bashrc: 사용자별 변수 설정

: 셸 파일은 전역적 파일과 지역적 파일로 나뉨

: 파일 /etc/profile.d는 몇몇 응용 프로그램들이 시작 시 자동 실행할 스크립트 파일 경로를 넣어둠

출처: https://thinking-developer.tistory.com/53 [생각하는 개발자:티스토리]


프로세스 관리 

1. 프로세스란

: CPU와 메모리를 할당받아 실행중인 프로그램

: 프로세스들마다 고유의 프로세스 ID, 즉 PID를 할당받는다

 

리눅스 프로세스 트리. 출처: https://slidesplayer.org/slide/11214656/

 

2. 프로세스의 유형

포어그라운드 프로세스 (Foreground Process)

: 사용자와 상호작용하는 프로세스

: 터미널에 직접 연결되어 입출력을 주고 받는 프로세스

: 명령 입력 후 수행 종료까지 기다려야하는 프로세스

: 화면에서 실행되는 것이 보이는 프로세스

: 예) 응용프로그램, 명령어 등

: fg %작업번호 (작업번호는 jobs 명령어로 확인가능)

 

백그라운드 프로세스 (Background Process)

:사용자와 직접적인 대화를 하지 않고 뒤에서 실행되는 프로세스

: 최상위 프로세스 init (PID: 1)

: 사용자의 입력에 관계없이 실행되는 프로세스

: 실행은 되지만 화면에 나타나지 않고 실행되는 프로세스

: 예) 시스템 프로그램, 데몬(Demon) 등

bg %작업번호&

 

데몬(Demon)

: 리눅스 시스템이 부팅 시 자동으로 실행되는 백그라운드 ㅡ로세스

: 메모리에 상주하면서 사용자의 특정 요청이 오면 즉시 실행되는 대기 중인 서버 프로세스

: 주기적이고 지속적인 서비스 요청을 처리하기 위해 사용

: 사용자들은 이 프로세스들을 볼 수 있는 권한이 없음

standalone inetd
- 데몬이 백그라운드에서 상시 대기하여 바로 요청처리
- 요청 시 바로 고속으로 처리
- 시스템 자원 많이 사용
- inetd의 확장 데몬인 xinetd의 요청이 있을 때만 동작
- 외부의 요청 시에만 저속으로 동작
- 리소스 소모가 적음


fork & exec

fork exec
- 새로운 프로세스를 만들 때 기존 프로세스를 복제
- 새로운 프로세스를 위한 메모리 할당
- 새로 생성된 프로세스는 원래의 프로세스와 똑같은 코드 有
- 원본 프로세스 = 부모 프로세스
- 복제 프로세스 = 자식 프로세스
-호출하는 프로세스가 새로운 프로세스로 변경
- 새로운 프로세스를 위한 메모리 할당 없음
- 호출한 프로세스의 메모리에 새로운 프로세스의 코드 덮어씌움

 

 

프로세스 상태 전이도. 출처: http://jangun.com/study/LINUX.html

출처: https://thinking-developer.tistory.com/54 [생각하는 개발자:티스토리]

 

SSH

옵션 내요
-a 인증 에이전트 전송을 불허
-e 세션에 대한 이스케이프 문자를 설정
-f 인증과 전송이 설정된 후에 백그라운드에서 ssh를 설정
-l 원격 시스템에 사용할 로그인 이름을 설정
-p 원격 호스트에 연결할 포트를 지정
-v 디버깅모드 자세한 정보 표시 모드를 활성
-x X11 전송을 불가능하게 설정
-L 지정된 원격 호스트와 포트에 전송할 로컬 포트 설정
-R 로컬 호스트와 지정된 포트로 전송될 원격 포트 설정

ex ) ssh [원격 계정]@[원격지_ip] -p [변경할 포트]    ( 포트 변경 시 지정해서 접속 )

      ssh [원격 계정]@[원격지_ip] netstat -ntl          ( 원격 접속 후 바로 수행할 명령문 입력도 가능합니다.)

1. 프로세스 관련 명령어

ps

: 현재 실행중인 프로세스의 상태를 프로세스 번호와 함께 출력해주는 명령어

: CPU 사용도가 낮은 순서로 출력

옵션

  • -a: 터미널과 연관된 모든 프로세스 출력
  • -u: 프로세스 소유자를 기준으로 출력
  • -x: 터미널에 종속되지 않은 프로세스도 출력 (예: 데몬)

상태코드

  • Z (zombie): 작업종료, 하지만 부모 프로세스부터 회수되지 않아 메모리를 차지하고 있을 경우
  • T (stopped): 작업 정지

 

ps 명령어 실행 결과

 

 

pstree

: 실행 중인 프로세스들을 트리 구조로 출력

 

jobs

: 작업이 중지된 상태, 박그라운드로 진행 중인 상태, 변경되었지만 보고되지 않은 상태 등 표시

: 백그라운드로 실행중인 프로세스를 확인

: [숫자]는 작업번호

: +는 실행중인 작업, -는 실행 예정 작업

 

bg/fg

: 포어그라운드에서 백그라운드로 전환 (bg %작업번호 또는 bg 작업번호)

: 백그라운드에서 포어그라운드로 전환 (fg %작업번호 또는 fg 작업번호)

: 작업 전환 전 실행중인 것은 잠시 정지 필요 (프로세스 시그널 전송 필요)

 

kill

: 프로세스를 번호(PID)를 사용하여 종료

: 시그널 목록을 확인하는 명령어 kill -l

: 특히 HUP, INT, QUIT, KILL, TERM, STOP, TSTP와 단축키에 관련해서는 매우 자주 출제됨

번호 시그널명 설명
1 HUP HangUP. 로그아웃 등 접속 종료 시
2 INT Interrupt. 일시정지. 단축키 Ctrl+C
3 QUIT 실행중지. 단축키 Ctrl+\
4 ILL Illegal Instruction
5 TRAP Trace Breakpoint에서 중지점 발생 시
9 KILL 프로세스 강제 종료
15 TERM 가능한 프로세스 정상 종료 - Default
18 CONT STOP으로 정지된 프로세스 실행
19 STOP 정지 시그널
20 TSTP 실행 정지 후 재실행을 위해 대기. 단축키 Ctrl+Z

 

killall

: 같은 데몬의 여러 연관된 프로세스들을 프로세스 이름으로 종료

 

nice

: 프로세스 사이의 우선순위를 확인하고, 프로세스명을 사용하여 우선순위를 변경할 수 있는 명령어

: 조정할 수 있는 NI값의 범위는 -20 ~ 19 (우선순위 높음 ~ 낮음)

: 우선순위 default 값은 0, 값이 작을수록 우선순위가 높다

: 옵션 -n을 사용하지 않으면 default는 10

: 조정 수치가 생략되면 명령의 우선권은 10만큼 증가

: 사용자가 조정가능한 NI 값에 따라, 실제 프로세스 우선순위인 PRI가 조정됨

예) nice -10 bash: bash 프로세스 값을 10만큼 증가 (우선순위 낮춤)

예) nice --10 bash: bash 프로세스 값은 10만큼 감소 (우선순위 높임)

 

renice

: 이미 실행중인 프로세스의 우선순위를 PID 번호를 사용하여 변경

: nice와 달리, 지정한 NI값으로 설정

예) nice 10 PID번호: PID번호에 일치하는 프로세스 NI값을 10으로 설정

예) nice -10 PID번호: PID번호에 일치하는 프로세스 NI값을 -10으로 설정

 

top

: 리눅스 시스템 운영 상태를 실시간으로 모니터링, 프로세스 우선순위 변경, 프로세스 상태 확인 명령어

: top는 합산한 CPI 사용률 출력 / ps는 특정시기 CPU 사용량을 출력

추가 입력 명령

  • q: 종료
  • k: 프로세스 kill-9
  • m: 메모리 ON/OFF
  • t: 프로세스와 CPU의 ON/OFF
  • p: 옵션 지정 프로세스 ID 출력
  • w: 설정 저장

 

top 명령어 실행 결과

 

 

nohup

: 프로세스가 중단되지 않고 백그라운드로 작업을 수행할 수 있게 함

: 사용자가 로그아웃하거나, 작업 중인 터미널 창이 닫혀도 실행 중인 프로세스를 백그라운드 프로세스로 계속 작업할 수 있도록 함

: 용량이 큰 데이터 압축 해제와 같은 실행이 오래 걸리는 프로세스들에 대해 nohup으로 처리하여 작업하면, 작업 중단 없이 해당 업무를 완료할 수 있음

: 해당 작업 중 표준 출력/에러는 nohup.out에 저장

: 백그라운드로 실행될 수 있도록 명령행 뒤에 &를 명시

 

tail

: 파일의 마지막 행을 기준으로 지정한 행까지 파일 내용의 일부를 출력

: 기본값으로 마지막 10줄을 출력

 

2. 스케줄링과 cron

cron/crontab

: 사용자가 주기적인 작업을 등록할 수 있도록 함

: 스케줄링 데몬은 crond

: 관리자 시스템 작업 내용은 /etc/crontab에 저장

: 시스템 개별 사용자용 작업 내용은 /var/spool/cron에 저장 

: [분] [시] [일] [월] [요일] [사용자명] [작업명령]

: n단위로 반복시에는 */n 로 표기

옵션

  • -i: 확인(information)
  • -l: 예약 작업 확인
  • -e: 예약 작업 편짐
  • -r: 예약 작업 삭제
  • -u 사용자명: root가 해당 사용자의 작업 삭제/편집/조회

출처: https://thinking-developer.tistory.com/55 [생각하는 개발자:티스토리]

 


 

 

에디터


에디터 종류

1. 개요

: 리눅스에서 지원하는 편집기로는 vi, emacs, nano, pico, gedit, xedit 등이 있음

: 리눅스 편집기는 편집기를 통해 파일을 수정

 

2. 종류

pico

: 워싱턴 대학의 Aboil Kasar가 개발한 유닉스 기반의 텍스트 에디터

: 메뉴 선택 방식의 텍스트 편집기로 기본 인터페이스가 윈도우의 메모장(notepad)과 유사

: 자유 소프트웨어 라이선스가 아니기 때문에 소스 수정이 불가능

: 다른 편집기에 비해 사용하기가 쉽고 편리하지만, 기능이 부족하고 업데이트가 잘 안됨

: 단락 정의, 맞춤법 검사, 복사 및 붙여넣기 가능

 

nano

 

 

: GNU 프로젝트에서 pico의 복제 버전 에디터인 nano를 개발

: 자동 들여쓰기, 정규표현식 검색, 구문 강조 등의 기능 제공

: 단축키를 통한 도움말 제공

 

emacs (잘나옴)

스톨만!!!! 고슬링!!

 

: 리처드 스톨만이 매크로 기능이 있는 텍스트 교정 및 편집기로 개발

: 최초의 개발자는 리처드 스톨만이며, 이후 제임스 고슬링이 LISP 언어를 기반하여 emacs에 다양한 기능 개발 추가

: LISP에 기반을 둔 환경 설정 언어를 가지고 있음

: 텍스트 뿐만 아니라 그래픽 모드도 지원

 

vi

빌조이!!!

: 1976년 빌 조이가 초기 BSD 릴리즈에 포함될 편집기로 개발

: 리눅스 배포판과 유닉스에 기본적으로 포함되어 있음

: 유닉스 환경에서 가장 많이 쓰이는 문서 편집기

: 다른 편집기들과 다르게 모드형 편집기

: 명령모드, 입력모드, 편집모드로 구성

: 지속적인 vi 에디터 설정은 .exrc 파일에 설정

 

vim

무레나르!!

 

 

: 브람 무레나르가 만든 편집기

: vi 편집기와 호환되면서 독자적으로 다양한 기능을 추가하여 만든 편집기

: 편집 시 다양한 색상을 이용하여 가시성을 높일 수 있음

: 패턴 검색 시 하이라이트 기능을 제공하여 빠른 검색을 가능하게 해줌

: ex모드에서 히스토리 기능을 제공

: 확장된 정규 표현식 문법과 강력한 문법 강조 기능을 가짐

 

gedit

 

 

: GNOME 데스크톱 환경으로 개발된 자유 소프트웨어 텍스트 편집기

: 마이크로소프트 윈도우, 맥 OS 등에서도 사용 가능

: UTF-8과 호환하며 텍스트 문서를 편집하는 용도에 중점을 두었음

: X 윈도우 시스템에 맞춰 개발되었음

: GTK+와 GNOME 라이브러리를 이용하여 개발되었음

: 텔넷 접속 시나 텍스트 기반 콘솔 창에서는 사용 불가

출처: https://thinking-developer.tistory.com/56 [생각하는 개발자:티스토리]

 

 

https://thinking-developer.tistory.com/57

1. pico 에디터 사용법

: Aboil Kasar 가 개발한 유닉스 기반의 텍스트 에디터

: 윈도우의 메모장(notepad)과 유사

: 쉽고 간편하지만, 기능이 부족하며 업데이트가 잘 되지 않음

 

 

단축키 기능
[Ctrl] + [O] 파일 저장
[Ctrl] + [X] 파일 종료. 종료 시 저장이 안되어 있으면 저장할 것인지 물어봄
[Ctrl] + [R] 현재 커서 위치에 다른 파일을 불러옴
[Ctrl] + [A] 현재 행의 맨 앞으로 이동
[Ctrl] + [E] 현재 행의 맨 끝으로 이동
[Ctrl] + [V] 이전 페이지로 이동
[Ctrl] + [Y] 다음 페이지로 이동
[Ctrl] + [C] 현재 커서의 위치를 표시
[Ctrl] + [T] 영문자의 철자를 확인
[Ctrl] + [W] 키를 누르고 문자열을 입력하면 원하는 문자열을 찾음
[Ctrl] + [K] 현재 라인을 삭제
[Ctrl] + [U] 마지막으로 삭제된 라인을 복구
[Ctrl] + [I] 화면 갱신

 

2. emacs 에디터 사용법

: 리처드 스톨만이 개발한 텍스트 교정 및 편집기

: 매크로 기능이 있음

: 이후 제임스 고슬링이 LISP 언어를 기반하여 다양한 기능을 추가

 

 

 

단축키 기능
[Ctrl] + [X]
[Ctrl] + [S]
파일 저장
[Ctrl] + [X]
[Ctrl] + [C]
편집 종료
[Ctrl] + [W] 잘라내기
[Ctrl] + [K] 커서 뒤에 있는 한 줄이 모두 지워짐
[Ctrl] + [A] 커서를 줄의 맨 앞으로 이동
[Ctrl] + [E] 커서를 줄의 맨 뒤로 이동
[Ctrl] + [P] 커서를 한 줄 위로 이동
[Ctrl] + [N] 커서를 한 줄 아래로 이동
[Ctrl] + [S] 커서의 아랫부분에서 찾을 문자열을 검색
[Ctrl] + [R] 커서의 윗부분에서 찾을 문자열을 검색
[Ctrl] + [G] 진행되고 있는 명령을 끔

 

3. vi 에디터 사용법

: 1976년 빌 조이가 초기 BSD 릴리즈에 포함시키기 위하여 개발한 편집기

: 리눅스 배포판과 유닉스에 기본적으로 포함되어 있음

: 유닉스 환경에서 가장 많이 쓰이는 문서 편집기

: 다른 편집기들과 다르게 모드형 현집기

: 명령모드, 입력모드, 편집 모드로 구성

: 지속적인 vi 에디터 설정은 .exrc에 설정

 

 

분류 단축키 기능
명령 모드에서
입력 모드로 전환
a 커서 다음(오른쪽)에 입력
A 행 마지막 부분에 입력
i 커서 앞(왼쪽)에 입력
I 행 처음 부분에 입력
o 커서 밑에 빈 행을 추가하여 입력
O 커서 위에 빈 행을 추가하여 입력
s 커서에 있는 글자를 지우고 입력
입력 모드에서
명령 모드로 전환
ESC 입력 모드에서 명령 모드로 전환
저장 및 종료 :q 종료
:q! 저장하지 않고 강제 종료
:wq 저장 후 종료
ZZ 저장 후 종료 (:wq와 동일)
:wq 파일 이름 저장 시 파일 이름 지정 가능
(비정상 종료시 .swp 파일 자동 생성)
커서 이동 h,j,k,l 좌, 하, 상, 우 커서 이동 (방향 키 없는 키보드 사용 시 사용)
w 다음 단어의 첫 글자로 이동
b 이전 단어의 첫 글자로 이동
G 마지막 행으로 이동
:숫자 지정한 숫자 행으로 이동 예) :5
삭제 x 커서에 있는 글자 삭제
X 커서 앞에 있는 글자 삭제
dw 커서 뒤에 있는 단어, 커서 포함 글자 삭제 (숫자 지정 가능)
db 커서 기준 앞에 있는 단어 글자 삭제 (숫자 지정 가능) 
dd 커서가 있는 라인(줄) 삭제 (숫자 지정 가능)
복사  yw 커서 뒤에 있는 단어, 커서 포함 글자 복사 (숫자 지정 가능)
yb 커서 앞에 있는 단어 글자 복사 (숫자 지정 가능)
yy 커서가 있는 라인(줄) 복사 (숫자 지정 가능
붙여넣기 p 커서 다음에 붙여넣기
P 커서 이전에 붙여넣기
찾기 /문자열 앞에서부터 문자열 찾기
?문자열 뒤에서부터 문자열 찾기
n 뒤로 검색
N 앞으로 검색
바꾸기 :%s/old/new 각 행의 처음 나오는 old를 찾아 new로 바꿈
:%s/old/new/g 모든 old를 찾아 new로 바꿈
:%s/old/new/gc 모든 old를 찾아 new로 바꾸기 전에 물어봄
되돌리기 u 이전으로 되돌리기 (undo)
다시실행 Ctrl + r 되돌리기 한 것을 다시 실행하기 (redo)
그 외 :set number 행 번호를 출력 (간단하게 :set nu)
:set nonumber 행 번호를 숨김 (간단하게 :set nonu)
:cd 현재 디렉토리 출력

출처: https://thinking-developer.tistory.com/57 [생각하는 개발자:티스토리]


소프트웨어

1. 계열

데비안(Debian) 계열

배포 업체: Debian, Ubuntu, Xandros, Linspire

패키지 툴: dbkg, apt-get, aptitude

 

레드햇(Red-Hat) 계열

배포 업체: Fedora, CentOS, RHEL, Mandirva

패키지 툴: rpm, yum->dnf 개선됨

 

오픈수세(OpenSUSE) 계열

패키지 툴: yaST, zypper



배포판   기본패키지관리기법       온라인패키지관리기법
레드햇        RPM                      YUM
데비안        Dpkg                    apt-get
수세          YaST                    zypper


rpm -ql~~~ : 패키지가 설치한 설치한 파일목록을 출력.
rpm -qa : 시스템에 설치된 모든 패키지 정보를 출력.
rpm -qip~~~.rpm : 패키지 파일에 대한 정보를 출력.
[검증(Verify)모드]
rpm -qV~~~ : 패키지를 검증한다.

 

2. 데비안 계열 패키지 툴

dpkg

: 데비안의 저레벨 패키지 관리 툴

: deb 패키지의 설치, 삭제, 정보 제공을 위해 사용

: 확장자는 .deb

: 패키지 설치 및 제거 시 rpm과 같은 의존성 무제 발생

옵션

  • i: 패키지 설치
  • l: (L의 소문자)설치된 패키지 목록 확인
  • I: (i의 대문자) 패키지 정보
  • s 패키지명: 지정된 패키지에 대한 자세한 정보
  • c: 패키지 파일 정보
  • L: 패키지 파일 목록
  • r: 환경 설정을 제외하고 패키지 제거
  • P: 환경 설정을 포함하여 패키지 제거

 

apt-get

 

 

: 데비안 리눅스에서 소프트웨어 설치와 제거를 위한 패키지 관리 유틸리티

: dpkg의 의존성 문제를 해결하기 위해 /etc/apt/source.list 파일 참조

 

 

aptitude

 

이미지 출처: https://www.tecmint.com/difference-between-apt-and-aptitude/

 

: 우분투 패키지 관리 유틸리티

: apt 처럼 패키지 관리를 자동화

 

3. 레드햇 계열 패키지 툴

rpm

 

 

: 레드햇 사에서 만들어냇 패키지 툴

: 새로운 패키지를 설치(옵션 i), 업그레이드(옵션 U)하거나, 삭제(옵션 e) 시 사용

: Windows의 setup.exe와 유사하게 만든 프로그램

: 레드햇 계열의 패키지 파일 확장명은 *.rpm

: 의존성 문제 때문에, 최근에는 yum 사용하는 것을 권장

옵션

  • v: 메세지 자세히 출력
  • h: 설치 과정을 '#'로 표시
  • V: 검증 과정 포함
  • F: 설치된 것만 업데이트하도록 함
  • q: 질의 시 사용하는 옵션
  • i: 질의시 패키지 정보도 함께 확인
  • a: 모든 패캐지 목록 확인
  • l: 패키지 내 모든 파일 확인
  • R: 의존성 정보 확인
  • f: 지정한 형태로 cnffur
  • [설치 시 주로 사용하는 옵션조합] ivh, Uvh, Fvh
  • [검색 시 주로 사용하는 옵션조합] qi, qa, ql, qf
  • [검증 시 주로 사용하는 옵션조합] Va

 

yum

 

 

: 네트워크를 통해 기존 rpm 패키지 파일의 업데이트 자동 수행

: 새로운 패키지 설치 및 제거 수행

: 명령어 저장소 주소는 /etc/yum.repos.d

: rpm의 의존성 문제를 해결하기 위한 유틸리티

: 인터넷을 기반으로 설치하므로 네트워크가 정상적으로 연결된 상태여야 함

: yum은 Fedora 22버전 이후부터 yum의 문제점을 보완한 DNF로 전환되고 있음

주요 명령어

  • install: 패키지 설치 (의존성있는 패키지도 함께 설치)
  • update: 패키지 업데이트 (-y 옵션을 줄 경우, 묻지 않고 모두 업데이트)
  • check-update: 업데이트 될 패키지의 목록을 출력
  • remove: 패키지 삭제 (의존성있는 패키지들도 함께 삭제)
  • list: 저장소 서버에 있는 모든 패키지 목록 확인
  • info: 패키지 정보 확인

 

4. 오픈수세 계열 패키지 툴

yaST

 

 

: 패키지 설치부터 부트로더 설정까지 제공하는 리눅스 통합관리 툴

: 포트 설정, SSHD 기능 설정, 방화벽 설정, 온라인 업데이트, 소프트웨어 설치/제거, 보조 장치 관리, 시스템 백업/복구, 네트워크 설정, 서버 설정, 방화벽, 사용자 관리 등의 기능을 제공

: 명령어 입력 없이도 이용 가능

 

zypper

 

 

: 오픈 수세 계열의 콘솔에서 프로그램 패키지 관리와 원본 저장소를 관리하는 유틸리티

: 용도는 원보 저장소 추가 및 제거, 프로그램 설치 및 삭제로 나뉘어짐

옵션

  • install: 패키지 설치
  • update: 패키지 업데이트
  • info: 패키지 정보 확인
  • se: 문자열과 연관된 패키지 이름 출력

출처: https://thinking-developer.tistory.com/58 [생각하는 개발자:티스토리]

 


 

설치 장치 설정

프린트관련
 1. BSD 계열

 

 
lpr : 작업을 요청하는 명령(라인 프린터 컨트롤)
lpq : 큐(Queue) 에 있는 작업의 목록을 출력는 명령
lprm : 큐에 대기중인 작업을 삭제하는 명령
lpc : 라인 프린터 컨트롤 프로그램, 프린터나 프린터 큐를 제어할 때 사용.


 2. System V 계열

 
lp : BSD 계열의 lpr 명령과 유사한 기능을혼다
lpstat : 큐의 상태를 출력 해주는 명령, 프린터 작업 상태를 확인할 수 있는 명령이다.
cancel : 작업을 취소하는 명령이다. lpstat를 요청 ID 를 확인해야 한다.
 

 


 3. 명령어 기준
 

출처: https://gocoder.tistory.com/1786 [고코더 IT Express:티스토리]

1. 파일 아카이브와 압축

파일 아카이브

: 아카이브는 다수 개의 파일이나 디렉터리를 하나의 파일로 묶는 것

: 아카이브 파일은 다른 시스템으로 다수 개의 파일을 한 번에 전송하거나 파일 백업용으로 사용

 

파일 압축과 해제

대표적인 파일 압축명과 압축률: 

(압축률 높음=파일이 작아짐) xz > bzip2 > gzip > compress (압축률 낮음= 파일이 큼)

  • compress ↔ uncompress: 유닉스에서 주로 사용. LZW 압축 알고리즘.
  • (tar 옵션: z) gzip ↔ gunzip: 가장 많이 사용. LZ77 알고리즘. 허프만 부호화 (-l 정보, -v 과정, -d 압축해제) - 
  • (tar 옵션: j) bzip2 ↔ bunzip2: 가장 많이 사용. 블록정렬 알고리즘. 허프만 부호화
  • ( tar 옵션: J) xz ↔ unxz: 가장 압축률이 높음

명령어 및 옵션

tar 명령어를 사용하여 다양한 압축명으로 압축 및 압축 해제 가능

  • -c: tar로 파일 묶기(압축)
  • -x: tar 압축 해제
  • -p: 파일 권한 저장
  • -v: 과정 출력
  • -f: 파일 이름 지정
  • -r: 마지막 추가
  • -t: 목록 나열
  • -C: 경로 지정
  • -z: gzip 압축/해제
  • -j: bzip2 압축/해제
  • -J: xz 압축/해제

cvf 기본적으로 압축한다고 생각하면 됨

xvf 기본적으로 압축 풀기

tvf 기본적으로 아카이브 내용 확인이라고 생각하면 됨

z : gz 파일관련

j : bz2 파일관련

* 은 항상 뒤에 붙는다 생각!!  "*" : 모든을 뜻함

2. 소스 코드 설치

[방법 1] configure → make (makefile) → make install

  1. 환경설정(configure): /configure 프로그램 설치 과정에서 필요로 하는 환경파일 makefile 생성
    ☞ 환경설정 파일의 역할: 어떤 프로그램을 컴파일하고 링크해야하는가를 make에게 설명해주는 역할
    ☞ make clean: configure로 생성된 다양한 파일 제거
  2. 컴파일(make makefile): make makefile을 기반으로 소스파일을 컴파일하여, 설치 파일(set up) 생성
    ☞ make dep: 컴파일 전 의존성 검사
  3. 파일 설치(make install): make install로 컴파일 된 실행파일을 지정된 속성으로 지정된 디렉터리에 설치

: 아카이브는 다수 개의 파일이나 디렉터리를 하나의 파일로 묶는 것

: 아카이브 파일은 다른 시스템으로 다수 개의 파일을 한 번에 전송하거나 파일 백업용으로 사용

 

[방법 2] cmake → make install

: cmake는 별도의 make 과정 없이 OS에 알맞는 makefile을 생성해줌으로써 훨씬 간편!

: MySQL 등이 사용

 

정리

  • 소스파일 컴파일 설치: gcc, make, tar, cmake
  • 패키지 파일 설치 (의존성 문제 有): rpm(redhat), dpkg(debian)
  • 자동 설치 도구: yum(redhat), apt-get(debian)

출처: https://thinking-developer.tistory.com/59 [생각하는 개발자:티스토리]

 


 

X 윈도  https://rich-mei.tistory.com/43

(1) x-윈도우의 특징과 구성요소

 

# 개념과 특징
- 리눅스 환경의 각종 애플리케이션과 유틸리티에 대해 그래픽 사용자 인터페이스(GUI)를 제공한다.

  참고] 원래 리눅스 환경은 CUI(Command User Interface)

- 플랫폼과 독립적으로 작동하는 그래픽 시스템이다.
- x-윈도우는 x11, x, x-windows system이라 부르기도 한다.

- 오픈 데스크톱 환경으로는 KDE, GNOME, XFCE 등이 있다.


- x-윈도우의 특징
 1) 네트워크 기반의 그래픽 환경을 제공한다.
 2) 이기종 시스템 사이에서도 사용 가능하다.

    참고] windows에서도 삼바와 같은 프로토콜을 이용하여 x-윈도우 화면을 이용할 수 있다.

 3) 스크롤바, 아이콘, 색상 등 그래픽 환경 자원들이 특정 형태로 정의되어 있지 않다.(표준화된 x-windows는 없음)
 4) 디스플레이 장치에 의존적이지 않으며 원하는 인터페이스를 만들 수 있다.

 

- x-윈도우는 네트워크 프로토콜(x프로토콜) 기반의 클라이언트/서버 시스템이다.
 > 서버 프로그램과 클라이언트 프로그램으로 나누어 작동한다.

    (두 개의 개별 소프트웨어 부분에 의해 제어)

 > 서버는 클라이언트의 디스플레이어 관련 접근 허용, 클라이언트 간의 자원 공유,

              네트워크 메시지 전달, 클라이언트와 입출력 기기의 중계를 담당한다.
 > 클라이언트는 애플리케이션으로 x 서버가 제공하는 기능들을 이용한다.

 

# 구성요소와 종류
1. XProtocol :

 - 서버와 클라이언트 사이에서 통신되는 Request, Reply, Event, Error의 기본 메시지이다.

 - 서버와 클라이언트 사이에서 정보를 주고받게 해주는 프로토콜

 - 메시지 교환방법 규정, 메시지 타입 규정 등 메시지 제어

2. Xlib :

 - 클라이언트에서 사용하는 라이브러리이다.

 - C나 리스프(LISP) 언어로 만들어짐

 - 윈도우 생성, 이벤트 처리, 창 조회, 키보드 처리 등의 라이브러리를 제공한다.
3. XCB :

 - 클라이언트에서 사용하는 라이브러리이다.

 - Xlib에서 XCB로 대체되어 현재는 XCB를 사용한다.

 - Xlib에서 지원하는 것을 모두 XCB에서 지원한다.

 - Xlib에 비해 향상된 쓰레드 기능을 가지며, 확장성이 좋다.
4. Xtookit :

 - 클라이언트에서 사용하는 라이브러리이다.

 - 고급레벨의 GUI 이용 가능하다. (위젯, GUI 구성하는 객체를 만들 수 있음)
5. XFree86 :

 - X 윈도우 시스템의 구현체

 - 인텔 x86운영체제에서 사용하는 서버 프로그램

 - 무료로 사용 가능

 - 다양한 환경 설정이 필요함(->xf86config에서 설정)
6. XF86Config :

 - XFree86의 환경설정을 담당(설정 파일)

 - 폰트, 키보드, 마우스, 모니터, 비디오 카드, 색상 등을 설정

 - '/etc/X11' or '/usr/X11R6/lib/X11'에서 볼 수 있다.

 - XF86Config는 세부적으로 세 개의 환경설정 파일로 나누어짐
    1) Xconfigurator
    2) XF86Config
    3) XF86setup

참고] 

xlib, xcb(저수준 라이브러리) -> GTK+, QT, FLTK, XFome 등의 라이브러리가 있다.
Xtoolkit(고수준 라이브러리) -> XView, Xaw, Motif, XtIntrinsics 등의 라이브러리가 있다.

 

 

(2) X-윈도우 설정과 실행

# 파일 /etc/inittab

- init 프로세스가 읽는 파일로, init 프로세스가 무엇을 해야할 것인가를 설정한다.
- 리눅스 사용 환경을 초기화한다.
- 형식) 이름 : 런레벨 : 옵션 : process -옵션

  ex> id:3:initdefault: -> 디폴트 런레벨을 3으로 지정 (initdefault 키워드 뒤에는 process 필드가 무시된다.)

런레벨 설명
0 halt (Do NOT set initdefault to this)
1 Single user mode
2 Multiuser, without NFS (The same as 3, if you do not have networking)
3 Full multiuser mode (CUI로 부팅)
4 unused
5 X11( x 윈도우로 부팅)
6 reboot (Do NOT set initdefault to this)

 

 # X-윈도우 실행

- 그래픽 환경이 아닌 터미널 윈도우로 로그인한 경우에는 몇 개의 프로그램을 실행해야 한다.
- 터미널 윈도우의 명령어 프롬프트상에서 다음의 명령어를 실행시켜야 한다.
- 형식) startx -- [인자값]

  (일반적으로 화면이 하나가 나오는데 인자값을 입력하면 여러 개의 X-윈도우 프로그램을 구동할 수 있다.)

- 명령어 startx는 X윈도우를 실행하는 스크립트로 시스템 환경을 초기화하고 xint(프로세스)를 호출한다.
- 명령어 startx 실행 시 인자값(argument)을 xinit에 전달하는 옵션은 '--'이다

-> 터미널 모드로 사용하다가 GUI로 변경하려면 startx -- 명령어를 사용

 

 # 환경변수 DISPLAY (x윈도우 관련 환경변수)

- 환경 변수는 프로세스가 컴퓨터에서 동작하는 방식에 영향을 주는 동적인 값이다.
- 셀에서 정의되고 실행하는 동안 프로그램에 필요한 변수이다.
- 환경변수 DISPLAY는 현재 x윈도우 display 위치를 저장할 수 있다.
- 형식) export DISPLAY=IP주소:디스플레이번호.스크린번호 (x윈도우 디스플레이 위치 변경 가능)

 

 

(3) 윈도우 매니저와 데스크톱 환경

가장 핵심은 데스크톱 매니저이다.
* 데스크톱 매니저 기반으로 윈도우 매니저, 디스플레이 매니저 활성화되어 사용

 

 # 윈도우 매니저

- 윈도우 매니저는 X-windows상에서 창(window)외 배치와 표현을 담당하는 시스템 프로그램이다.
- 창 열기와 닫기, 창의 생성 위치, 창의 크기 조정, 창의 외향과 테두리를 변화시킬 수 있다.
- 라이브러리는 Xlib와 XCB를 사용한다.
- 리눅스에서 사용 가능한 윈도우 매니저들은 다양하다.
- 윈도우 매니저의 대표적인 종류로는 fvwm, twm, windowMaker, AfterStep 등이 있다.

 

# 데스크톱 환경(Desktop Environment 또는 Desktop Manager)

- GUI 사용자에게 제공하는 인터페이스 스타일로 데스크톱 관리자라고도 한다.
- 윈도우 매니저, 파일 관리자, 도움말, 제어판 등 다양한 도구를 제공하는 패키지 형태의 프로그램이다.
- 아이콘, 창, 도구 모음, 폴더, 배경화면, 데스크톱 위젯도 제공한다.
- 드래그 앤 드롭(drag & drop)과 프로세스 간의 통보 가능을 지원한다.
- 대표적인 데스크톱 환경에는 KDE, GNOME, LXDE, xfce 등이 있다.

   (가장 일반적인 것은 KDE, GNOME)

- 데스크톱 환경에 따라 아이콘, 창, 도구모음, 폴더 등이 다르게 지원

QT라이브러리는 KDE 환경에서 사용.
GTK+는 GNOME 환경에서 사용.

 

 # 디스플레이 매니저

- X window system상에서 작동하는 프로그램이다.

  (데스크톱 환경을 설치하면 데스크톱 환경이 사용하는 디스플레이 매니저가 있다)

- 1988년 XTIR3에서 xdm 디스플레이 매니저가 도입되었다.
- 1989년 XTIR4에서 원격제어가 가능하도록 xdmcp(X Display Manager Control Protocol)가 도입되었다.
- 디스플레이 매니저 종류들로는 XDM, GDM, KDM, dtlogin 등이 있다.
- 로컬 또는 리모트 컴퓨터의 X server의 접속과 세션 시작을 담당한다.
- 사용자에게 그래픽 로그인 화면을 띄워주고 아이디와 패스워드를 입력받아 인증을 진행한다.

- 인증이 정상적으로 완료되면 세션을 시작한다.

참고]

XDM : 초창기 사용했으며 현재는 거의 사용하지 않는다.
KDM : KDE 데스크톱 환경에서 사용하는 디스플레이 매니저이다.

GDM : GNOME 데스크톱 환경에서 사용하는 디스플레이 매니저이다. /

         GNOME 그래픽 로그인 프로그램을 담당한다. / 

         gtk 라이브러리를 이용해서 구현되고 있다. /

         gnu, gpl기반의 라이센스를 따르고 있다. /

 

(1) 원격지에서 X 클라이언트 이용

 - (원격지에 있는 서버를 접속하기 위해서 클라이언트들이 이용하는 명령어 : xhost, xauth가 있다.)
 - (접속을 위해서 인증 필요)


xhost : ip주소기반
xhost + : 모든 호스트 허용
xhost - : 모든 호스트 거부
xhost   : 현재 상태 확인
xauth : 인증키 기반
서버에서 인증키 생성 -> 클라이언트 보냄 -> 홈디렉터리에 저장

 

 # xhost :

 - IP나 도메인명을 이용해서 서버 접속 요청
 - 명령어 xhost는 X 서버에 접속할 수 있는 클라이언트를 지정하거나 해제한다.
 - x 서버에게 디스플레이를 요청 시 해당 요청에 대한 허용 거부를 호스트 단위로 제어한다.
 - 형식) xhost [+][-] [ip|도메인명]

   (특정 IP를 기재하지 않으면 모든 호스트 접속 허용/금지)

 - 환경변수 DISPLAY로 x 서버 프로그램이 실행될 때 표시되는 클라이언트 주소를 지정한다.

 

 # xauth :

 - xauth는 .Xauthority 파일의 쿠키 내용을 추가, 삭제, 리스트를 출력하는 유틸리티이다.

(.Xauthority 파일에는 mit magic cookie1값을 가지고 있고 이 값을 기반으로 사용자 인증을 하고, 인증된 사용자만 x 서버의 서비스를 클라이언트가 받을 수 있다.)

 - 쿠키 값(키) 기반의 인증으로 인증 절차가 xhost보다 강화된 방법
 - xhost가 호스트 기반 인증 방식을 사용하기 위해 필요한 유틸릴티라면, xauth는 MMC방식(사용자 인증 기반)의 인증 방식을 사용하기 위한 필수 유틸리티이다.
 - 원격지에서 접속하는 x 클라이언트를 허가할 때 IP 주소나 호스트명이 아닌 x-윈도우 실행 시에 생성되는 키 값으로 인증할 때 사용한다.
 - 사용자 인증 기반을 지원하기 위해 각 사용자에게 네트워크화된 홈 디렉터리에 파일 $HOME/.Xauthority에 대해 읽기 및 쓰기 권한이 있어햐 한다.
 - 형식) xauth [옵션]

 

(2) X윈도우 응용프로그램

응용프로그램 설명
오피스 LibreOffice 오피스 프로그램 패키지
Gedit 텍스트 편집 프로그램
Kwrite KDE 기반의 텍스트 편집기
그래픽 GIMP 이미지 편집 프로그램
ImageMegick 이미지를 생성 및 편집을 지원하는 프로그램
Eog GNOME의 이미지 뷰어 프로그램
Kolourpaint Ubuntu이미지 편집 프로그램
Gthumb GNOME 데스트콥 이미지 뷰어 프로그램
Gwenview KDE의 기본 이미지 뷰어
멀티미디어 Totem GNOME 기반의 사운드 및 비디오 재생 프로그램
RHYTHMBOX 통합형 음악 관리 프로그램
CHEESE GNOME 기반의 카메라 동영상 프로그램
개발 ECLIPSE 통합 개발 환경으로 자바를 비롯한 다양한 언어를 지원
기타 Colphin KDE용 파일 관리자
KSnapshot 스크린샷 프로그램

 

인터넷 활용
(1) WWW(World Wide Web) 서비스 (웹 서비스)

 - 프로토콜 HTTP(Hyper Text Transfer Protocol)를 기반으로 한 멀티미디어와 하이퍼텍스트를 통합한 정보 검색 시스템

 - 인터넷에 연결된 전 세계 컴퓨터의 모든 문서들을 언제 어디서든 다양한 컴퓨터 환경에서 검색이 가능하게 해줌

 - 다양한 그래픽 유저 인터페이스들을 사용하는 것이 가능

 - 분산 클라이언트-서버 모델을 기반으로 함(1대의 서버에 여러 대의 클라이언트가 접속하여 서비스를 받음)

 - 1989년 CERN(유럽입자 물리학 연구소)에서 하이퍼텍스트가 시작되었으며,

   1990년 WWW라는 넥스트 플랫폼용 브라우저가 공개됨

 - 표준 웹 프로토콜(HTTP, XML, SOAP, WSDL, UDDI)을 기본으로 하여

   서로 다른 개발 환경과 운영체제에서도 상호 통신이 가능

 - 다양한 웹 브라우저들이 있음

 

(2) 메일 서비스

 - 전자 메일 시스템은 컴퓨터 사용자끼리 편지를 주고받는 서비스

 - MTA(메일 서버에 메일을 전달), MUA(메일을 작성하는 사용자 인터페이스),

   MDA(수신자 메일 박스에 메일 전달)로 구성

 - 메일 클라이언트에서 송신은 SMTP(메일발송/서버간 메일교환),

   수신은 POP3 or IMAP4(메일 서버에 도착한 메일을 사용자 컴퓨터에서 확인) 를 이용

 - MIME(Multipurpose Internet Mail Extension)은 멀티미디어 전자우편을 위한 표준,

   멀티미디어 데이터를 ASCll 형식으로 변환할 필요 없이 인터넷 전자 우편으로 송신하기 위한 SMTP의 확장 규격

   (메일 송신 프로토콜)

 

(3) FTP 서비스(파일전송 프로토콜)

 - FTP(File Transfer Protocol) TCP/IP에 의해 제공되는 호스트 간의 파일 복사를 위한 프로토콜

 - 통신 모드 : 패시브 모드(passive mode: FTP 서버가 지정한 포트로 클라이언트가 트래픽 송수신) /

                  액티브 모드(active mode : 클라이언트가 요청한 포트로 FTP 서버가 트래픽 송수신)

 - 사용 포트 : 20번(일반 데이터 전송용), 21번(제어 데이터 전송용) 포트

 - FTP는 사용자 계정을 가진 사용자들의 접속과 익명(anonymous)의 로그인 허용

 

(4) DNS(Domain Name System) 서비스

 - 호스트 이름을 기반으로 IP 주소로 변환(또는 조회) 하거나

   IP 주소를 기반으로 호스트 이름으로 변환/조회 시켜주는 프로토콜

 - DNS에서는 도메인명을 분산된 트리 형태의 계층적 구조로 관리

 - 일반 최상위 도메인(generic top-level domain, gTLD)은 특정한 조직 계열에 따라 사용

 - 도메인 길이는 3글자 이상, 조직의 종류에 따라 사용하는 이름이 다름

 

(5) Telnet와 SSH 서비스

 - 네트워크상에 있는 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령 실행/파일 복사 등을 제공

 - 사용자 서버에 접속하여 서버 관리/파일 편집 등을 Text 모드 환경에서 명령을 실행하고 결과를 화면을 통해 볼 수 있다

 - Telnet은 서버와 주고 받는 정보를 Byte 스트림 형식으로 전송

 - SSH는 DES,RSA 등의 암호화 기법을 사용해서 전송/ 압축 기술 제공

 

(6) NFS(Network Fiile System)

 - 네트워크 기반에 다른 시스템과 파일 시스템을 공유하기 위한 클라이언트/서버 프로그램

 - 1984년 썬 마이크로시스템즈 사에서 개발

 - 원격지에 있는 리눅스 서버의 특정 디렉터리를 로컬 시스템의 하위 디렉토리 처럼 사용 가능

 - 다른 컴퓨터의 파일 시스템을 마운트하고 공유하여 자신의 디렉터리인 것처럼 사용할 수 있음

 - Portmap이 먼저 수행되어 있어야만 NFS 서비스가 실행됨

 - Portmap은 NIS, NFS 등 RPC(Remote Procedure Call) 연결에 관여하는 데몬

 - NFS 서비스는 nfsd, rpc.mounted, rpc.statd, rpc.rocked, rpc.rquotad 데몬들이 구동됨

 

(7) RPC(Remote Procedure Call)

 - 동적으로 서비스와 포트를 연결할 때 사용하는 방법

 - 기본적으로 포트와 서비스가 정적으로 구성될 때는 /etc/services 파일을 참조

 - 동적으로 포트를 할당 받아 사용할 때는 RPC인 rpcbind(SUN에서는 sunrpc)를 사용


 (1) 네트워크 인터페이스 설정

  - 리눅스는 다양한 네트워크 인터페이스를 지원

    (ex>LoopBack 인터페이스, ethernet 인터페이스, DL 인터페이스, Parallel Line  인터페이스, 슬랩 인터페이스,

          ppp 인터페이스 :WAN구간 연결 또는 전화모뎀이랑 연결하여 통신이 가능하게 해 줌 )

  - 일반적으로 네트워크 인터페이스는 자동으로 인식되지만 자동으로 인식되지 않을 경우 수동으로 설정해야함

  - 네트워크 인터페이스 수동 설정 방법은 컴파일된 인터페이스 모듈을 커널에 적재하는 것

    해당 모듈을 커널에 적재하는 방법은 수동 적재 방법과 자동 적재 방법이 있다

    ( * 수동: insmod 명령어를 이용해 적재, lsmod 명령어로 적재되었는지 확인 /

      * 자동:etcmodprove.conf 파일에 모듈 정보 세팅 시 다음 부팅 시 자동으로 적재됨)

 

(2) 네트워크 설정 파일들

  - 배포본 마다 파일명 차이가 있음

  - 네트워크 환경 설정 정보 ex>IP, 서브넷 마스크, 게이트웨이 DNS 등..

  - /etc/sysconfig/network : 네트워크의 기본 정보가 설정되어 있는 파일 (DNS 주소 기입하지 않음)

  - /etc/sysconfig/network-scripts/ifcfg-ethX : 지정된 네트워크 인터페이스의 네트워크 환경 설정 정보가 저장 

    (DNS 주소 기입하지 않음)

  - /etc/resolv.conf : 기본적으로 사용할 도메인명과 네임서버를 설정(DNS 주소 기입됨)

    (cf> DNS 주소가 입력되어 있지 않으면 네트워크는 정상적으로 돌아가나 인터넷이 안 되는 것처럼 보임)

  - /etc/hosts : IP 주소와 도메인 주소를 1:1로 등록하여 도메인에 대한 IP 주소를 조회(lookup)하도록 함

    (내 컴퓨터가 DNS처럼 작동할 수 있게 됨)

  - /etc/host.conf : DNS 서비스를 제공할 때 먼저 이 파일을 검사하여 파일의 설정에 따라 서비스함

    (DNS 환경 설정을 제어함)

 

 # IP 주소 설정(= TCP/IP 설정) <- 네트워크 인터페이스를 인식시키려면 네트워크 설정을 해야 함

   - 네트워크 설정 파일로 주소 설정 :

      /etc/sysconfig/network 또는 /etc/sysconfig/network-scripts/ifcfg-ethX로 IP 주소 할당

   - 명령어를 이용한 주소 설정 :

     명령어 ifconfig를 이용해 IP 주소 할당

   - 유틸리티를 이용한 주소 설정 :

     netconfig, system-config-network, redhat-config-network 등의 다양한 유틸리티를 이용하여 주소를 할당

 

 # 라우팅 테이블 설정 및 관리

   - 라우팅이란 송신 패킷이 목적지까지 전송할 수 있도록 경로를 설정하는 작업

   - 송신 패킷은 라우팅 테이블에 목적지 경로 정보가 있다면 해당 경로로 패킷을 전송

   - 명령어 route은 라우팅 테이블 설정하거나 확인

     (옵션 net : 목적지 네트워크, dev : 어떤 인터페이스를 통해 트래픽을 내보낼지 설정)

   - 목적지 경로가 라우팅 테이블에 없다면 디폴트 게이트웨이로 트래픽을 전송할 수 있게 라우팅 테이블을 설정할 수 있다.

($ route add default gw ....)

 

(3) 네트워크 관련 명령어

 TCP/IP 주소 설정 정보 확인  ifconfig, nslookup
 네트워크 경로 상태 확인  ping, traceroute
 네트워크 연결 상태 확인  netstat
 라우팅 테이블 확인  route
 NIC 상태 확인(랜카드 상태 네트워크 인터페이스 상태)  ethtool, mii-tool, arp

 

 ifconfig : 네트워크 인터페이스 구성 정보 확인

              (인터페이스 MAC 주소, IP 제대로 설정되어 있는지, 활성화되어 있는지 등 확인 가능)

 nslookup : DNS 서버를 기반으로 특정 호스트의 IP 찾아줌

 ping : 목적지까지 트래픽 전송이 가능한지 확인

 traceroute : ping 사용하여 목적지까지 트래픽 전송되지 않을 시 어느 구간에서 문제가 발생하는지 확인(장애구간), 어떤 경로를 통해 트래픽이 전달되는지 확인

 route : 라우팅 테이블 확인, 게이트웨이 주소 값 확인 가능, 라우팅 테이블 구성 시에도 사용

 netstat : 전송 제어 프로토콜, 라우팅 테이블, 네트워크 프로토콜 통계 정보나 연결 상태 정보 확인 가능

             (옵션 r:라우팅 테이블 확인, n:IP주소 형태나 포트 번호 확인, s: 프로토콜 정보도 보여줌)

 mii-tool : 네트워크 인터페이스 속도, 전송 모듈 확인(하프드 플래스, 풀드 플래스..), 인터페이스가 몇 메가 속도 지원하는지 확인 가능

 ethtool : 물리적 연결 허브 연결뿐 아니라 mii-tool보다 상세한 네트워크 인터페이스 상태 정보 확인 가능

 arp : 동일한 LAN 내에 연결된 컴퓨터의 IP 주소를 얻는 데 사용(ARP 테이블 확인)

        (보통 컴퓨터는 arp 테이블을 가지고 있음) ip를 가진 호스트의 MAC 주소를 1:1로 기록해 놓음

 

 

응용분야

 

 

 



cron 분 시 일 월 요일 

 

alsa 사운드

sane 스캐너

cups  애플이 개발한 소스프린팅

oss 사운드 만들고 캡쳐
LPRng 버클리 프린팅 시스템 BSD 계열 유닉스에서 사용하기 위해 개발 / 프린터 스풀링 , 네트워크 프린트

 

 

LVM : https://tech.cloud.nongshim.co.kr/2018/11/23/lvmlogical-volume-manager-1-%EA%B0%9C%EB%85%90/

2005년 설립된 Qumranet에서 개발한 하이퍼바이저.
x86 시스템 기반으로 cpu 전 가상화 방식, QEMU라는 cpu 에뮬레이터 사용

 

VG(볼륨 그룹) : PV 가 모여 만들어진 그룹

PV(물리적 볼륨) :  디스크를 LVM에서 사용할 수 있게 변환하는 작업

LV(논리 볼륨) : VG 에서 사용자가 필요한 만큼 할당돼서 만들어지는 공간 (사용자가 필요한 만큼 할당하여 쓰게 되는 파티션) 

PE(물리적 확장) : PV에서 나누어 사용하는 일종의 블록 기본4MB

LE(논리적확장) :  LV에서 나누어 사용하는 일종의 블록 기본 4MB

 

만드는 순서 23년 9월 기출 : PV -> VG -> LV

 

 

 

 

 


https://it-life.tistory.com/161 이미지참고

고계산용(HPC) 클러스터 : 베어울프라고도 불림 (과학계산용)

부하분산 클러스터 

고가용성(HA) 클라스터 : 메인과 백업 / 부하분산기

 


tvf

2109 11번문제

 


2309

 

 

cvf : 새로운 tar파일 만들때

zcvf : tar로 묶고 gzip으로 압축

xvf : tar파일을 풀때

zxvf : gzip으로 압축 풀기

tvf : 내용을볼때 

rvf : 마지막에 파일추가 

ztvf : 압축안풀고 내용만 확인

 

 

편집기 관련문제

 

 

치환하는 문제 

 

 

2309

 

 

 

vi편집기 단축어 공부하기

 

Rpm 명령어



윈도 매니저

X-윈도우상에서 윈도우의 배치와 표현을 담당 / kwin

 

데스크톱 환경

GUI 환경을 이용하기 위해 사용자에게 제공되는 인터페이스

 

디스플레이 매니저

X-윈도우 구성요소 중 사용자 로그인 및 세션 관리 역할 수행 프로그램

 

데스크톱 매니저

XDM, GDM, KDM 등이 존재

 

 

------

8진수 권한표기

파일은 666 / 디렉토리는 777에서 시작

 

 

> 666에서 002 빼면

664 > -rw-rw-r--

 

 

 

 

lsblk

 

 

Blkid 

 

 

Fdisk

 

 

Df

 

 

 

fsck

e2fsck

xfs.fsck

xfs_repair

 

 

Evince

PDF 문서 뷰어 프로그램

 

Gimp

이미지 편집, 변환, 생성 프로그램

 

Eog

이미지 뷰어 프로그램

 

Gwenview

KDE에서 제공하는 이미지 뷰어 프로그램

 

ImageMagicK

비트맵 이미지를 보여주고 생성 및 편집 지원

 

Totem

Move Player(미디어 플레이어)

 

 

2309월

 

2309월 52번

데스크톱 환경 https://honglab.tistory.com/34

 

 

레이드 관련 

https://smsinfo.tistory.com/177

cups 프린트 서버

sane : 스캐너

also : 사운드 

OSS : 초기리눅스 사운드 (캡쳐)

프린트관련 명령어 

 

BSD 

lpr : 프린터 출력

lprm : 대기 작업 삭제

lpc : 프린터 제어

lpq : 큐에 있는 작업 목록 출력

 

System V 계열

cancel : 취소, 무조건 작업번호 붙여야함

lpstat : 작업번호 확인

lp : 프린터 출력 (n 매수설정)

 


LibreOffice Writer -> 워드프로세서

 

LibreOffice Dreaw -> 드로잉프로그램

 

LibreOffice Calc -> 엑셀스프레드시트(엑셀)

 

LibreOffice Impress -> 파워포인트



 xauth

  • MMC 방식의 인증 방식을 사용하기 위한 필수 유틸리티
  • 생성한 키 값을 확인할 때 사용하는 명령
  • ex) # xauth list $DISPLAY

 

 

Xlib

  • 저수준(저기능) 인터페이스
  • C언어로 구현된 클라이언트 라이브러리
  • X서버와 대화하는 역할을 수행

 

 

시스템 시작 시 X 윈도 모드로 부팅이 되도록 설정하는 명령은?

= systemctl set-default runlevel5.target


25 모드설정

    가) 종류

        ① X 윈도 모드(RunLevel 5)

        ② 텍스트 모드(RunLevel 3)

    나) X 윈도 -> 텍스트

        ① systemctl set-default multi-user.target

    다) 텍스트 -> X 윈도

        ① systemctl set-default graphical.target

 

 

 

 

 

 

GNU 프로젝트때 만들어진거

Gnome (d이미지프로그램)

NANO - 메모장 pico 복제판 라이선스때문에 만듬
BASH - 본쉘 복제판

 

패키지관리 

데비안 리눅스 : dpkg 

레드헷 리눅스 : Rpm yum def 

 

 

Suse 리눅스 패키지 관리

Zipper 

Arch 계열 paceman

 

bash -본 셸을 기반으로 하여 GNU 프로젝트에 의해 개발되었다.

 

tcsh -켄 그리어가 테넥스(TENEX)라는 운영체제에 명령행 완성기능을 반영하게 되었고, 1981년 C셸과 통합해서 만들었다. C 셸의 기능을 강화시킨 셸로 명령어 완성기능, 명령행 편집기능 등을 추가로 지원한다. -명령행 편집 기능을 제공하는 확장 C셸

csh -버클리 대학의 빌 조이가 개발한 것으로 C언어를 기반으로 만들어졌다. -히스토리 기능, 별명(Alias)기능, 작업제어 등의 기능을 포함하였다

ksh -AT&T사의 데이비드 콘이 개발하였고, 명령어 완성 기능 및 히스토리 기능을 제공한다.

dash posix 와 호환되는 /bin/sh를 작게 구현하여 빠른 수행 / 현재 데비안 및 우분트 계열의 리눅스

 

Vi 편집기 관련

Set nu : 각 행 번호가 나타나다록 설정 : 취소하고싶으면 set nonu 

Set no : 다양한 설정 비활성화

Set ai : 자동 들여쓰기 (auto indent) 윗줄과 같은 열에 커서

Set list : 공백이나 특수문자 시각화해줌 

set ic

set sm

set ts

 

편집 모드실행

 

 

Top : Cpu 사용률 확인  

Nice : 우선순위 설정  renice  우선순위변경

Pstree  : 프로세스 트리 출력

 

Jobs 백그라운드 직업 확인하는 명령어 : jobs

Bg : 중지된 작업을 백그라운드에서 실행 

Fg : 백그라운드에서 포그라운드로 변경 

Nohup (no hangup) : 터미널 세션이 종료되어도 백그라운드에서 실행중인 프로세스가 종료되지않고 계속실행됨

 

~/.bashrc : alias

 /etc/passwd : 로그인 셸을 변경했을때 저장되는 파일 

 /etc/shells : 사용가능한 쉘 목록을 저장함

/etc/profile : 시스템 전체 사용자에게 적용하는 환경 변수와 시작 관련 프로그램 설정하는 파일
/etc/hosts : 가상도메인 , 네트워크 실습용
/etc/reslov.conf : nameserver <ip주소> 적혀있음

 

-------------------

권한 관련 

Quota 
현재 사용자 단위 쿼터 정보를 출력

(사용자 디스크 쿼터 설정 정보만 확인)

 

Edquota
편집기(editor)를 사용하여 그룹에 디스크 사용량 할당

  • edquota -a : 특정 사용자의 쿼터를 다른 사용자에게 동일하게 설정
  • edquota -p 이름1 이름2 : 이름1에게 설정된 쿼터를 이름2에게도 적용하기 위한 방법

 

Re quota  시스템 단위 쿼터 정보를 요약하여 출력

xfs_quota 사용자의 디스크 사용량을 제한할 때 사용하는 명령어

 

set quota : vi 안쓰고 직접명령어로 (문제에서 vi로 보통내기때문에 edquota)

Chmod

Chown

Chgrp

Umask

ls : 파일이나 디렉토리에 부여된 소유권 값 확인

 

fdisk  파티션을 생성, 삭제
fdisk -I 정보출력 

 

Df (마운팅된 디스크 용량정보)
디스크 남은공간(용량)에 대한 정보를 보여줌

  • 시스템에 마운트된 하드디스크의 남은 용량을 확인
  • -i : 에러가 발생하면 추가로 원인을 파악하기 위한 명령어 // inode
  • -T : 파일시스템의 종류를 확인할 때 입력하는 옵션 // -t : 유형
  • -h : 사람이 읽을 수 있는 형태

 

 

Du  (전체 용량정보)
디스크 사용공간에 대한 정보를 보여줌

  • 디렉터리별 디스크 사용량
  • 파일이나 디렉터리들이 디스크에 차지하고 있는 용량을 출력할때 사용
  • -du -sh /* : / 이하에 있는 각 디렉터리별로 크기를 합쳐서 사람이 읽기 좋은 단위로 출력하기 위한 명령

 

Mount

 

blkid 블록 디바이스 파일시스템 유형이나 속성 출력

 

lsblk  blkid 보다 더 자세하게 출력

 

 

 

Fstab  6가지 정보

 

[파일시스템 장치] [마운트 포인트] [파일시스템 종류] [옵션] [덤프] [파일체크옵션]




네트워크관련 ---------------
https://limqoh.tistory.com/entry/linux0002-1   반드시 다시 볼거
ISO : OSI 7계층

IEEE : LAN, MAN 관련 표준
ICANN : IP
EIA : RS-232 케이블
ANSI : fddi 광섬유케이블


주요포트
1 20(active),21(passive) = FTP

  1. 22 = SSH
  2. 23 = Telnet
  3. 25 = SMTP
  4. 53 = DNS
  5. 69 = TFTP
  6. 80 = HTTP
  7. 110 = POP3
  8. 123 = NTP
  9. 143 = IMAP
  10. 161,162 = SNMP
  11. 443 = HTTPS
  12. 929,990 = FTPS
  13. 9418 = git

 

 

netstat ; 소켓의 PID 및 프로그램명과 포트번호를 출력함

 

스타형 : 중앙 컴퓨터 / 일부장애에도 상관없다 / 단말기 추가나 오류진단에 좋다

버스형 : 연결된 수에따라 성능이 좌우/ 신호 간섭을 막기위해 종간기가 존재 / 구조가 간단하여 제거, 설치비용이 좋다

링형 : 토큰패싱, 전송상의 충돌이 없고 노드 숫자가 늘어도 성능저하가 적다

망형 : 장애발생시 서로 영향이 적다(신뢰성 높음) / 라우터이용하거나 백본망 / 고장 지점 찾기 어려움

 

 

Ansible : 프로비저닝, 레드헷인수

Docker : 하이퍼바이저나 os 없이 이미지를 만들어서 동작 (컨테이너로 실행 2013년)

Kubernetes : 컨테이너 관리

 

타이젠

webos

genivi : BMW, GM, 인텔 등 자동차용 IVI

 

최상위 도메인

com / net/ kr / org

 

ip : 네트워크정보 관련 출력

arp : MAC주소 조회

telnet

route : 패킷을 전송할 수 있도록 목적지까지 경로를 설정 및 관리하는 명령어

ethtool 네트워크 인터페이스의 물리적 연결 상태를 확인하는 명령어(이더넷)

ss : SYN Flooding 공격과 같은 네트워크 상태 정보 확인

 

IPv4 128 bit / Ip4 32bit

 

 

 

 

 

게이트웨이 주소 값 

 

230909 문제

서브넷 
서브넷 255.255.255.192 는  
1111.1111.1111.1100 이니  (128/64/32/16/8/4/2/1)
ip 뒷자리만 보면 됨  그중에서 1100 이므로 11이 포함된 앞자리 2개만 보면 됨

66은 
01000010 이니  (64+2) 앞 2자리(01)만 가져오고  01에서 00000 / 01에서 111111 추가

01000000 ~ 01111111 까지보면 되는데 (맨처음 1000000은 네트워크주소 / 마지막 01111111 은 멀티캐스트 주소라서 제외시켜야함)
가능한 주소는 64초과 ~ 127미만까지가능  

 


 

 

220903 문제 

 

서브넷 
서브넷 255.255.255.192 는  
1111.1111.1111.1100 이니  (128/64/32/16/8/4/2/1)
ip 뒷자리만 보면 됨  그중에서 1100 이므로 11이 포함된 앞자리 2개만 보면 됨

150은 
10010110 이니 

10000000 ~ 10111111 까지보면 되는데 (맨처음 1000000은 네트워크주소 / 마지막 10111111 은 멀티캐스트 주소라서 제외시켜야함)
가능한 주소는 128초과 ~ 191미만까지가능  


211211 문제

 

 

서브넷 255.255.255.192 는  
1111.1111.1111.1100 이니  (128/64/32/16/8/4/2/1)


1111.1111.1111.1100 이니  (128/64/32/16/8/4/2/1)
ip 뒷자리만 보면 됨  그중에서 1100 이므로 11이 포함된 앞자리 2개만 보면 됨

129은 
10000001 이니 
10000000 ~ 10111111 까지보면 되는데 (맨처음 1000000은 네트워크주소 / 마지막 10111111 은 멀티캐스트 주소라서 제외시켜야함)
가능한 주소는 128초과 ~ 191미만까지가능  

근데 브로드캐스트값을 물어봤으니 10111111 : 191이 됨


210313 브로드캐스트 주소

 

서브넷 
서브넷 255.255.255.192 는  
1111.1111.1111.1100 이니  (128/64/32/16/8/4/2/1)
ip 뒷자리만 보면 됨  그중에서 1100 이므로 11이 포함된 앞자리 2개만 보면 됨

157 
10011101 이니  2자리만 보고 나머지는 1로 채우면 끝

10000000(128) ~ 10111111(191)   은 128+63 = 191

브로드 캐스트를 물어봤으니 191

https://yozm.wishket.com/magazine/detail/2299/ : 기획자가 알아야할 내용 정리

'글적글적 > 방향성' 카테고리의 다른 글

취업 방향  (0) 2023.02.20
개발 공부를 하게된 이유, 해야 하는 이유  (0) 2022.12.06

나스에다가 GPU 넣는다면?
https://zimacube-boosters-15.kckb.st/02c22ee9


AI 서버대용 으로 괜찮을지도?

컴퓨터비전관련해서는 
24시간 딥러닝모델을 돌릴 서버가 필요한데 일반 데톱은 전기세 때문에 살짝 고민...

 

Intel Atom C3538

 

 

https://www.synology.com/en-global/products/DVA

사실 이미 시놀로지가  DVA 모델이 있지만 하드웨어대비 가격이 너무나 비싸다 사실상 소프트웨어 가격...

Model synology zimacube pro
CPU Intel Atom C3538 Intel i5 1235U
GPU GTX RTX A2000 12g
RAM - not included (Max 32G) 64G included (Max 64G) 
OS DSM / Surveilance DVA  Zima OS / 
bay 4bay  6+1 / 4bay + 2 + 1 onboard
Price $2499 (amazon) $1599 (Kickstarter)



음 그냥 데톱을 사서 사무실에 박아둘까? 아니면 직접 코딩해서 세팅할지 흠...


GPU가 들어간 크리에이터팩

회사에서 포트고정시켜주거나 포트포워딩 할 일이 많아서 게이트웨이 찾아가야할 때가 있는데

종종 헷갈려서 메모해두기

 

Terminal 일단 열고

 

 

내부/ 외부 IP 주소


# 내부
ipconfig getifaddr en0

ifconfig | grep inet



# 외부(공인)
curl ifconfig.me

 

 

 

 

 

게이트웨이 

route get default

'Network > [IOT]' 카테고리의 다른 글

[IOT] "Siri" 대신 "ChatGPT" 호출하기  (0) 2023.03.05
[Network] 네트워크 개념  (0) 2022.11.28
[Network] IP주소 클래스(A,B,C class)란?  (0) 2022.11.13

sqld 자격검정 실전문제 pdf 및 기출문제 덤프
채팅문의

 

MMdetection을 사용하기 위한 초기 환경설정

 

1. 상환경 구

conda create -n mmdetection python=3.11 # ( 3.7 이상 버전이면 ok)

 

2. Pytorch 설

conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia

 

3. MMCV-Full 설


자신이 설한 cuda 버전으로 설합니다. 우리는 위에 11.7 했으므로 11.7

pip install mmcv==2.0.0 -f https://download.openmmlab.com/mmcv/dist/cu117/torch2.0/index.html

가이드 주소 : https://mmcv.readthedocs.io/en/latest/get_started/installation.html#install-mmcv

 

 

4. Github 에서 mmdetection zip 다로드 후 파이참 세팅 및 위에서 만상환경으로 인터프린 트 설정

https://github.com/open-mmlab/mmdetection/archive/refs/heads/main.zip

or 

git clone https://github.com/open-mmlab/mmdetection.git

 

5. install MMDetection (수동 설치)   / cd명령어로 저장한 파일로 경로이동

pip install -r requirements/build.txt

pip install -v -e .

pip mmdet # 설치가 잘 됐는지 확인사살

'ComputerVision > [ObjectDetection]' 카테고리의 다른 글

[ObjectDetection] Keypoint 탐지  (0) 2023.08.01

keypoint가 라벨링된 json 파일(train)을 이용하여 이미지에 적용하여 학습하여

나머지 이미지(test)로 keypoint 찾기

 

# keypointrcnn_resnet50_fpn 모델 이용한 Keypoint 실습

PyTorch 제공하는 Object detection reference training scripts 다운로드

 - 다운로드 사이트  https://github.com/pytorch/vision/tree/main/references/detection 

 

 

 

Customdataset.py

import torch
import json
import cv2
import numpy as np
import os
from torch.utils.data import Dataset
from torchvision.transforms import functional as F


class KeypointDataset(Dataset):
    def __init__(self, root, transform=None, demo=False):
        self.demo = demo
        # Visualize를 통해 시각화로 확인하고자 할때 비교를 위한 변수
        self.root = root
        # 현재 데이터셋은 root 인자에 dataset 하위 폴더의 train, test 폴더를 택일하도록 되어 있음
        self.imgs_files = sorted(os.listdir(os.path.join(self.root, "images")))
        # 이미지 파일 리스트. train 또는 test 폴더 하위에 있는 images 폴더를 지정하고, 해당 폴더의 내용물을 받아옴
        # 이미지를 이름 정렬순으로 불러오도록 sorted를 붙임
        self.annotations_files = sorted(os.listdir(os.path.join(self.root, "annotations")))
        # 라벨링 JSON 파일 리스트. 상기 images 폴더를 받아온 것과 동일
        self.transform = transform

    def __getitem__(self, idx):
        img_path = os.path.join(self.root, "images", self.imgs_files[idx])
        # 이번에 호출되는 idx번째 이미지 파일의 절대경로
        annotations_path = os.path.join(self.root, "annotations", self.annotations_files[idx])
        # 이번에 호출되는 idx번째 이미지 파일의 라벨 JSON 파일 경로

        img_original = cv2.imread(img_path)
        img_original = cv2.cvtColor(img_original, cv2.COLOR_BGR2RGB)
        # 이미지를 읽은 후, BGR 순서를 RGB 형태로 바꿈

        with open(annotations_path, "r", encoding="utf-8") as f:
            data = json.load(f)
            # 라벨 JSON 파일을 JSON 모듈로 받아옴
            bboxes_original = data["bboxes"]
            # JSON 하위 "bboxes" 키로 bbox 정보들이 담겨있음
            keypoints_original = data["keypoints"]
            # "keypoints" 키로 키포인트 정보가 담겨있음
            bboxes_labels_original = ['Glue tube' for _ in bboxes_original]
            # 현재 데이터셋은 모든 객체가 접착제 튜브이므로,
            # 모든 bbox에 대해 일관적으로 'Glue tube'라는 라벨을 붙여줌

        if self.transform:  # if self.transform is not None:
            # "keypoints": [
            #   [[1019, 487, 1], [1432, 404, 1]], [[861, 534, 1], [392, 666, 1]]
            # ]
            keypoints_original_flattened = [el[0:2] for kp in keypoints_original for el in kp]
            # kp : [[1019, 487, 1]]
            # el : [1019, 487, 1]
            # el[0:2] : [1019, 487] (평면 이미지에서 3번째 축 요소는 필요없기 때문에 제거)
            # keypoints_original_flattened = [[1019, 487], [1432, 404], [861, 534], [392, 666]]
            # albumentation transform은 평면 이미지에 적용되므로 2차원 좌표만이 필요함

            # albumentation 적용
            transformed = self.transform(image=img_original, bboxes=bboxes_original,
                                         bboxes_labels=bboxes_labels_original,
                                         keypoints=keypoints_original_flattened)

            img = transformed["image"]  # albumentation transform이 적용된 image
            bboxes = transformed["bboxes"]

            keypoints_transformed_unflattened = np.reshape(np.array(transformed["keypoints"]), (-1, 2, 2)).tolist()
            # transformed["keypoints"] : [1019, 487, 1432, 404, 861, 534, 392, 666]
            # keypoints_transformed_unflattened : [[[1019, 487], [1432, 404]], [[861, 534], [392, 666]]]

            keypoints = []
            for o_idx, obj in enumerate(keypoints_transformed_unflattened):
                obj_keypoints = []
                # o_idx : 현재 순회중인 요소의 순번 (index)
                # obj : 현재 순회중인 요소, ex) [[1019, 487], [1432, 404]]
                for k_idx, kp in enumerate(obj):
                    # k_idx : 현재 순회중인 하위 요소의 순번 (index)
                    # kp : 현재 순회중인 요소, ex) [1019, 487]
                    obj_keypoints.append(kp + [keypoints_original[o_idx][k_idx][2]])
                    # torch.Tensor에서 벡터곱을 하는 과정에서 필요할 3번째 축 요소를 덧붙임 ex) [1019, 487, 1]
                keypoints.append(obj_keypoints)
                # Tensor 형태로 사용할 keypoints 리스트에 3번째 축 요소를 덧붙인 키포인트 좌표를 담음

        else:
            img, bboxes, keypoints = img_original, bboxes_original, keypoints_original
            # transform이 없는 경우에는 변수 이름만 바꿔줌

        # transform을 통과한 값들을 모두 tensor로 변경
        bboxes = torch.as_tensor(bboxes, dtype=torch.float32)
        # as_tensor 메서드가 list를 tensor로 변환할 때 속도 이점이 있음
        target = {}
        # keypoint 모델에 사용하기 위한 label이 dictionary 형태로 필요하므로, dict 형태로 꾸림
        target["boxes"] = bboxes
        target["labels"] = torch.as_tensor([1 for _ in bboxes], dtype=torch.int64)
        # 모든 객체는 동일하게 접착제 튜브이므로, 동일한 라벨 번호 삽입
        target["image_id"] = torch.tensor([idx])
        # image_id는 고유번호를 지칭하는 경우도 있는데, 그러한 경우에는 JSON 파일에 기입이 되어있어야 함
        # 이번 데이터셋은 JSON상에 기입되어있지 않으므로, 현재 파일의 순번을 넣어줌
        target["area"] = (bboxes[:, 3] - bboxes[:, 1]) * (bboxes[:, 2] - bboxes[:, 0])
        # 해당하는 bbox의 넓이.
        # bboxes[:, 3] - bboxes[:, 1] : bboxes 내부 요소들의 (y2 - y1), 즉 세로 길이
        # bboxes[:, 2] - bboxes[:, 0] : bboxes 내부 요소들의 (x2 - x1), 즉 가로 길이
        target["iscrowd"] = torch.zeros(len(bboxes), dtype=torch.int64)
        # 이미지상에 키포인트 또는 bbox가 가려져있는지를 묻는 요소
        target["keypoints"] = torch.as_tensor(keypoints, dtype=torch.float32)

        img = F.to_tensor(img)
        # image의 텐서 변환

        bboxes_original = torch.as_tensor(bboxes_original, dtype=torch.float32)
        target_original = {}
        target_original["boxes"] = bboxes_original
        target_original["labels"] = torch.as_tensor([1 for _ in bboxes_original],
                                                    dtype=torch.int64)  # all objects are glue tubes
        target_original["image_id"] = torch.tensor([idx])
        target_original["area"] = (bboxes_original[:, 3] - bboxes_original[:, 1]) * (
                bboxes_original[:, 2] - bboxes_original[:, 0])
        target_original["iscrowd"] = torch.zeros(len(bboxes_original), dtype=torch.int64)
        target_original["keypoints"] = torch.as_tensor(keypoints_original, dtype=torch.float32)
        img_original = F.to_tensor(img_original)
        # demo=True일 경우, 원본 이미지와 변환된 이미지를 비교하기 위해 원본 이미지를 반환하기 위한 블록

        if self.demo:
            return img, target, img_original, target_original
        else:
            return img, target

    def __len__(self):
        return len(self.imgs_files)


if __name__ == "__main__":
    root_path = "./keypoint_dataset"
    train_dataset = KeypointDataset(f"{root_path}/train")
    for item in train_dataset:
        print(item)

 

 

visualize.py

import cv2
import albumentations as A
from Customdataset import KeypointDataset
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
from utils import collate_fn


train_transform = A.Compose([
                    A.Sequential([
                        A.RandomRotate90(p=1), # 랜덤 90도 회전
                        A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, brightness_by_max=True,
                                                   always_apply=False, p=1) # 랜덤 밝기 및 대비 조정
                    ], p=1)
                ], keypoint_params=A.KeypointParams(format='xy'),
                   bbox_params=A.BboxParams(format="pascal_voc", label_fields=['bboxes_labels']) # 키포인트의 형태를 x-y 순으로 지정
                )

root_path = "./keypoint_dataset/"
dataset = KeypointDataset(f"{root_path}/train/", transform=train_transform, demo=True)
# demo=True 인자를 먹으면 Dataset이 변환된 이미지에 더해 transform 이전 이미지까지 반환하도록 지정됨
data_loader = DataLoader(dataset, batch_size=1, shuffle=True, collate_fn=collate_fn)

iterator = iter(data_loader)
# for문으로 돌릴 수 있는 복합 자료형들은 iterable (반복 가능) 속성을 갖고 있음
# iter()로 그러한 자료형을 감싸면 iterator (반복자) 가 되고,
# next(iterator)를 호출하면서 for문을 돌리듯이 내부 값들을 순회할 수 있게 됨
batch = next(iterator)
# iterator에 대해 next로 감싸서 호출을 하게 되면, 
# for item in iterator의 예시에서 item에 해당하는 단일 항목을 반환함
# 아래 4줄에 해당하는 코드와 같은 의미
# batch_ = None
# for item in data_loader:
#     batch_ = item
#     break

keypoints_classes_ids2names = {0: "Head", 1: "Tail"}
# bbox 클래스는 모두 접착제 튜브 (Glue tube) 로 동일하지만, keypoint 클래스는 위의 dict를 따름


def visualize(image, bboxes, keypoints, image_original=None, bboxes_original=None, keypoints_original=None):
    # pyplot을 통해서 bbox와 키포인트가 포함된
    # 원본 이미지와 변환된 이미지를 차트에 띄워서 대조할 수 있는 편의함수
    fontsize = 18
    # cv2.putText에 사용될 글씨 크기 변수

    for bbox in bboxes:
        # bbox = xyxy
        start_point = (bbox[0], bbox[1])
        # 사각형의 좌측 상단
        end_point = (bbox[2], bbox[3])
        # 사각형의 우측 하단
        image = cv2.rectangle(image.copy(), start_point, end_point, (0, 255, 0), 2)
        # 이미지에 bbox 좌표에 해당하는 사각형을 그림

    for kpts in keypoints:
        # keypoints : JSON 파일에 있는 keypoints 키의 값 (즉, keypoints 최상위 리스트)
        # kpts : keypoints 내부의 각 리스트 (즉, 각 bbox의 키포인트 리스트)
        for idx, kp in enumerate(kpts):
            # kp : kpts 내부의 각 리스트 (즉, 키포인트 리스트 내부의 xy좌표쌍, 키포인트 점)
            image = cv2.circle(image.copy(), tuple(kp), 5, (255, 0, 0), 10)
            # 현재 키포인트에 점을 찍음
            image = cv2.putText(image.copy(), f" {keypoints_classes_ids2names[idx]}", tuple(kp),
                                cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3, cv2.LINE_AA)
            # 현재 키포인트가 Head인지 Tail인지 위에 선언한 dict에 해당하는 문자를 집어넣음

    # 변환된 이미지만을 확인할 경우, 원본 이미지가 없을 것이므로 그대로 이미지 처리 끝냄
    if image_original is None and keypoints_original is None:
        plt.figure(figsize=(40, 40))
        # 이미지를 그릴 차트 선언
        plt.imshow(image)
        # 위에서 bbox와 키포인트를 그린 이미지를 출력

    else:
        for bbox in bboxes_original:
        # bbox = xyxy
            start_point = (bbox[0], bbox[1])
            # 사각형의 좌측 상단
            end_point = (bbox[2], bbox[3])
            # 사각형의 우측 하단
            image_original = cv2.rectangle(image_original.copy(), start_point, end_point, (0, 255, 0), 2)
            # 이미지에 bbox 좌표에 해당하는 사각형을 그림

        for kpts in keypoints_original:
            # keypoints : JSON 파일에 있는 keypoints 키의 값 (즉, keypoints 최상위 리스트)
            # kpts : keypoints 내부의 각 리스트 (즉, 각 bbox의 키포인트 리스트)
            for idx, kp in enumerate(kpts):
                # kp : kpts 내부의 각 리스트 (즉, 키포인트 리스트 내부의 xy좌표쌍, 키포인트 점)
                image_original = cv2.circle(image_original.copy(), tuple(kp), 5, (255, 0, 0), 10)
                # 현재 키포인트에 점을 찍음
                image_original = cv2.putText(image_original.copy(), f" {keypoints_classes_ids2names[idx]}", tuple(kp),
                                    cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3, cv2.LINE_AA)
                # 현재 키포인트가 Head인지 Tail인지 위에 선언한 dict에 해당하는 문자를 집어넣음
        
        f, ax = plt.subplots(1, 2, figsize=(40, 20))
        # 두 장의 이미지를 1행 2열, 즉 가로로 길게 보여주는 subplots 생성

        ax[0].imshow(image_original)
        # 첫번째 subplot에는 원본 이미지를 출력
        ax[0].set_title("Original Image", fontsize=fontsize)
        # 이미지 제목

        ax[1].imshow(image)
        # 두번째 subplot에는 변환이 완료된 이미지를 출력
        ax[1].set_title("Transformed Image", fontsize=fontsize)

        plt.show()


if __name__=="__main__":

    visualize_image_show = True
    visualize_targets_show = True

    image = (batch[0][0].permute(1, 2, 0).numpy() * 255).astype(np.uint8)
    # CustomDataset에서 Tensor로 변환했기 때문에 다시 plt에 사용할 수 있도록 numpy 행렬로 변경
    # img, target, img_original, target_original = batch이므로, batch[0]는 img를 지칭
    # batch[0][0]에 실제 이미지 행렬에 해당하는 텐서가 있을것 (batch[0][1]에는 dtype 등의 다른 정보가 있음)
    bboxes = batch[1][0]['boxes'].detach().cpu().numpy().astype(np.int32).tolist()
    # target['boxes']에 bbox 정보가 저장되어있으므로, 해당 키로 접근하여 bbox 정보를 획득

    keypoints = []
    for kpts in batch[1][0]['keypoints'].detach().cpu().numpy().astype(np.int32).tolist():
        keypoints.append([kp[:2] for kp in kpts])
        # 이미지 평면상 점들이 필요하므로, 3번째 요소로 들어있을 1을 제거

    image_original = (batch[2][0].permute(1, 2, 0).numpy() * 255).astype(np.uint8)
    # batch[2] : image_original
    bboxes_original = batch[3][0]['boxes'].detach().cpu().numpy().astype(np.int32).tolist()
    # batch[3] : target

    keypoints_original = []
    for kpts in batch[3][0]['keypoints'].detach().cpu().numpy().astype(np.int32).tolist():
        keypoints_original.append([kp[:2] for kp in kpts])

    if visualize_image_show:
        visualize(image, bboxes, keypoints, image_original, bboxes_original, keypoints_original)
    if visualize_targets_show and visualize_image_show == False:
        print("Original targets: \n", batch[3], "\n\n")
        # original targets: (줄바꿈) original targets dict 출력 (두줄 내림)
        print("Transformed targets: \n", batch[1])

 

 

main.py

import torch
import torchvision
import albumentations as A

from engine import train_one_epoch, evaluate
from utils import collate_fn

from torch.utils.data import DataLoader
from Customdataset import KeypointDataset

from torchvision.models.detection import keypointrcnn_resnet50_fpn
from torchvision.models.detection.rpn import AnchorGenerator

def get_model(num_keypoints, weights_path=None):
    # 필요한 모델에 대해 키포인트 개수를 정의하고, 기존 모델이 있는 경우 로드하는 편의함수
    anchor_generator = AnchorGenerator(sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0))

    # 여러 input size에 대해 feature map으로 넘어갈 때 적절한 비율 변환율을 도와주는 객체

    model = keypointrcnn_resnet50_fpn(
                        pretrained=False, # 모델 자체는 pretrain된 것을 사용하지 않음
                        # 현재는 학습용 코드이기 때문에, pretrain 모델을 fine-tuning 하지않고 처음부터 가중치 업데이트를 하도록 설정

                        pretrained_backbone=True, # backbone만 pretrain된 것을 사용함
                        # backbone은 모델 설계상 이미 pretrain 됐을 것으로 상정했기 때문에
                        # 실제 가중치 없데이트가 주로 일어날 부분에 비해 pretrain 여부가 크게 상관있지 않음
                        num_classes=2, # 무조건 배경 클래스를 포함함
                        num_keypoints=num_keypoints,
                        rpn_anchor_generator=anchor_generator)
    if weights_path: # 기존 모델이 있는 경우
        state_dict = torch.load(weights_path)
        model.load_state_dict(state_dict)

    return model

train_transform = A.Compose([
                    A.Sequential([
                        A.RandomRotate90(p=1), # 랜덤 90도 회전
                        A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, brightness_by_max=True,
                                                    always_apply=False, p=1) # 랜덤 밝기 및 대비 조정
                    ], p=1)
                ], keypoint_params=A.KeypointParams(format='xy'),
                      bbox_params=A.BboxParams(format="pascal_voc", label_fields=['bboxes_labels']) # 키포인트의 형태를 x-y 순으로 지정
                )

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

KEYPOINTS_FOLDER_TRAIN = "./keypoint_dataset/train/"
# train dataset이 있는 경로
train_dataset = KeypointDataset(KEYPOINTS_FOLDER_TRAIN, transform=train_transform)
train_dataloader = DataLoader(train_dataset, batch_size=6, shuffle=True, collate_fn=collate_fn)

model = get_model(num_keypoints=2)
model.to(device)

optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=0.0005)
# momentum : 이전에 가중치를 업데이트한 기울기를 얼마나 반영할 것인가?
# weight_decay : 가중치 감소율
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.3)
# stepLR : step_size epoch 마다 lr이 기준 lr * gamma 로 변경됨 -> 즉 5 epoch 마다 lr이 0.3배씩 줄어듬

num_epochs = 20
# 최대 학습 횟수

# 현재 engine에서 받아온 train_one_epoch 함수는 손실함수를 넣지 않아도 되도록 처리된 함수이므로,
# 손실함수의 정의 는 생략됨

for epoch in range(num_epochs):
    train_one_epoch(model, optimizer, train_dataloader, device, epoch, print_freq=1000)
    # 학습이 진행되는 함수
    lr_scheduler.step()
    # 학습 1 epoch가 끝날때마다 scheduler 역시 업데이트
    if epoch % 10 == 0:
        torch.save(model.state_dict(), f"./keypointsrcnn_weights_{epoch}.pth")
        # 10 epochs마다 가중치 저장

torch.save(model.state_dict(), "./keypointsrcnn_weights_last.pth")
# 모든 epoch가 끝나면 last.pth까지 저장

'ComputerVision > [ObjectDetection]' 카테고리의 다른 글

MMdetection 설치 A-Z  (0) 2023.08.03

학습데이터를 변형시켜 마치 다른 학습데이터처럼 만들기 : 한장의 사진으로 여러장의 학습데이터를 만들 수 있다.

 

import cv2
import matplotlib.pyplot as plt
import numpy as np

image = cv2.imread("image02.jpeg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# #### rotation ####
# angle = 30

# h, w = image.shape[:2]
# center = (w//2, h//2)
# M = cv2.getRotationMatrix2D(center, angle, 1.0)
#     # getRotationMatrix2D(중심 좌표, 회전 각도, 크기 변환 비율)

# rotated_img = cv2.warpAffine(image, M, (w, h))
#                 # warpAffine(원본 이미지, 회전 행렬, 이미지 크기)

# plt.imshow(image)
# plt.show()

# plt.imshow(rotated_img)
# plt.show()
# #### rotation ####

#### zoom ####
# h, w = image.shape[:2]

# zoom_scale = 4 # 이미지 확대/축소 배율
# enlarged_img = cv2.resize(image, (w*zoom_scale, h*zoom_scale), interpolation=cv2.INTER_CUBIC)
#             # resize(원본 이미지, (최종 너비, 최종 높이), 이미지 보간 방법 (ex: cv2.INTER_CUBIC))
# center = [enlarged_img.shape[0] // 2, enlarged_img.shape[1] // 2]
# cut_half = 300
# zoomed_img = enlarged_img[center[0]-cut_half:center[0]+cut_half, center[1]-cut_half:center[1]+cut_half]
# plt.imshow(zoomed_img)
# plt.show()
#### zoom ####


#### shift ####

# shift = (0, 50)
# M = np.float32([
#     [1, 0, shift[0]],
#     [0, 1, shift[1]]
# ])
# # 이동 행렬: 좌측 2x2 -> 회전 행렬 (현재 단위행렬), 우측 1열: 이동 행렬 (x 변위, y 변위)

# shifted_img = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# plt.imshow(shifted_img)
# plt.show()
#### shift ####

#### flip ####
# flipped_img_updown = cv2.flip(image, 0) # 상하반전
# flipped_img_leftright = cv2.flip(image, 1) # 좌우반전
# flipped_img_lr_other = cv2.flip(image, -1) # 상하 & 좌우반전

# plt.imshow(image)
# plt.show()
# plt.imshow(flipped_img_updown)
# plt.show()
# plt.imshow(flipped_img_leftright)
# plt.show()
# plt.imshow(flipped_img_lr_other)
# plt.show()
#### flip ####

#### salt-and-pepper noise ####
# noise = np.zeros(image.shape, np.uint8) # uint8 = unsigned int 8-bit (부호 없는 1바이트 정수)
# cv2.randu(noise, 0, 255)
# black = noise < 30 # [True, True, False, False, False, ...] 형태의 Mask 생성
# white = noise > 225
# noise[black] = 0
# noise[white] = 255

# noise_b = noise[:, :, 0] # image.shape (h, w, c) -> h*w*c -> color channel : B, G, R
# noise_g = noise[:, :, 1]
# noise_r = noise[:, :, 2]
# noisy_img = cv2.merge([
#     cv2.add(image[:, :, 0], noise_b),
#     cv2.add(image[:, :, 1], noise_g),
#     cv2.add(image[:, :, 2], noise_r)
# ])

# plt.imshow(image)
# plt.show()
# plt.imshow(noisy_img)
# plt.show()
#### salt-and-pepper noise ####


#### Gaussian Noise ####
# mean = 0
# var = 100
# sigma = var ** 0.5

# gauss = np.random.normal(mean, sigma, image.shape)
# gauss = gauss.astype('uint8')

# noisy_img = cv2.add(image, gauss)

# plt.imshow(noisy_img)
# plt.show()
#### Gaussian Noise ####


#### 색조 변경 ####
# RGB , HSV 
# hsv_img = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
# hue_shift = 30
# hsv_img[:, :, 0] = (hsv_img[:, :, 0] + hue_shift) % 180
# rgb_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)

# plt.imshow(image)
# plt.show()
# plt.imshow(rgb_img)
# plt.show()
#### 색조 변경 ####


#### 색상 변환 ####
# hsv_img = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)

# # hsv[h, w, c]
# hsv_img[:, :, 0] += 50 # Hue -> 50도 증가
# hsv_img[:, :, 1] = np.uint8(hsv_img[:, :, 1] * 0.5)  # 채도
# hsv_img[:, :, 2] = np.uint8(hsv_img[:, :, 2] * 1.5)  # 밝기

# # imshow <- BGR / RGB 로 강제로 디코딩
# rgb_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
# plt.imshow(rgb_img)
# plt.show()
#### 색상 변환 ####


#### 이미지 크롭 ####
# x, y, w, h = 300, 300, 200, 200  # (100, 100) 좌표에서 (200 * 200) 크기로 자를 것임
# crop_img_wide = image[y-h:y+h, x-w:x+w] # (x, y) 를 중심으로 2w, 2h 크기로 자름
# crop_img_lt = image[y:y+h, x:x+w] # (x, y) 를 기점으로 (w, h) 만큼 오른쪽 아래로 간 크기로 자름

# plt.imshow(image)
# plt.show()
# plt.imshow(crop_img_wide)
# plt.show()
# plt.imshow(crop_img_lt)
# plt.show()
#### 이미지 크롭 ####

#### warpAffine ####
# x_diff = 50
# y_diff = 100
# h, w, c = image.shape
# M = np.float32([
#     [1, 0, x_diff],
#     [0, 1, y_diff]
# ]) # x축으로 50, y 축으로 100 이동하는 병진이동행렬
# shifted_img = cv2.warpAffine(image, M, (w, h))

# M = cv2.getRotationMatrix2D((w // 2, h // 2), 45, 1.0)
# rotated_img = cv2.warpAffine(image, M, (w, h))

# M = cv2.getRotationMatrix2D((w // 2, h // 2), 0, 0.5)
# halfed_img = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_AREA) # 가장자리를 검은색으로 칠한, 원본 이미지 크기와 같은 축소 이미지
# croped_img = halfed_img[h//2 - h//4 : h//2 + h//4, 
#                         w//2 - w//4 : w//2 + w//4] # 가장자리를 잘라낸 이미지

# resized_img = cv2.resize(image, (w//2, h//2), interpolation=cv2.INTER_AREA)
# plt.imshow(image)
# plt.show()
# plt.imshow(shifted_img)
# plt.show()
# plt.imshow(rotated_img)
# plt.show()
# plt.imshow(resized_img)
# plt.show()
# plt.imshow(halfed_img)
# plt.show()
# plt.imshow(croped_img)
# plt.show()
#### warpAffine ####

#### blurring ####
# blur_img = cv2.GaussianBlur(image, (5, 5), 5)

# plt.imshow(blur_img)
# plt.show()
#### blurring ####

#### adaptive threshold ####
# img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

# thresh = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# # ADAPTIVE_THRESH_MEAN_C: 적응형 임계값 처리, 임계값 기준을 평균치를 사용함
# # 인자 11: 블록 크기, 11x11 블록으로 이미지를 나눈 후 해당 영역
# plt.imshow(img_gray, 'gray')
# plt.show()
# plt.imshow(thresh, 'gray')
# plt.show()
#### adaptive threshold ####


#### 색온도 보정 ####
# org_img = image.copy()
# balance = [0.8, 0.7, 0.8]

# for i, value in enumerate(balance):
#     if value != 1.0:
#         org_img[:, :, i] = cv2.addWeighted(org_img[:,:,i], value, 0, 0, 0)
#                             # addWeighted: src에 대해 value만큼의 가중치로 색온도 조절

# plt.imshow(org_img)
# plt.show()
#### 색온도 보정 ####


#### 모션 블러 ####
# kernal_size = 15
# kernal_direction = np.zeros((kernal_size, kernal_size))
# kernal_direction[int((kernal_size)//2), :] = np.ones(kernal_size)
# kernal_direction /= kernal_size # 커널의 합이 1이 되도록
# kernal_matrix = cv2.getRotationMatrix2D((kernal_size/2, kernal_size/2), 45, 1)
# kernal = np.hstack((kernal_matrix[:, :2], [[0], [0]]))
#         # kernal_matrix[:, :2] <- 회전 행렬에서 병진이동 벡터를 제외하고 회전 행렬 값만 가져옴
#         # [[0],[0]] <- 병진이동 벡터 (이동 X)
# kernal = cv2.warpAffine(kernal_direction, kernal, (kernal_size, kernal_size))

# motion_blur_img = cv2.filter2D(image, -1, kernal)
# plt.imshow(motion_blur_img)
# plt.show()
#### 모션 블러 ####


#### 난수 노이즈 ####
# gray_img = cv2.imread('image02.jpeg', cv2.IMREAD_GRAYSCALE)
# h, w = gray_img.shape

# mean = 0
# var = 100
# sigma = var ** 0.5

# gaussian = np.random.normal(mean, sigma, (h, w))
# noisy_image = gray_img + gaussian.astype(np.uint8)
# # uint8 -> 0 ~ 255
# cv2.imshow("", noisy_image)
# cv2.waitKey()
#### 난수 노이즈 ####

#### 채도 조정 ####
# img = cv2.imread('image02.jpeg')
# org_img = img.copy()

# img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# saturation_factor = 1.5
# img_hsv[:, :, 1] = img_hsv[:, :, 1] * saturation_factor

# saturated_img = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)

# cv2.imshow("", org_img)
# cv2.waitKey()
# cv2.imshow("", saturated_img)
# cv2.waitKey()
#### 채도 조정 ####


#### 밝기 조정 ####
# img = cv2.imread('image02.jpeg')
# org_img = img.copy()

# bright_diff = 50
# img_brighten = cv2.convertScaleAbs(img, alpha=1, beta=bright_diff)

# cv2.imshow("org", org_img)
# cv2.imshow("brighten", img_brighten)
# cv2.waitKey()
#### 밝기 조정 ####

#### 노이즈 제거 ####
# img_filtered = cv2.medianBlur(image, 5)
# plt.imshow(image)
# plt.show()
# plt.imshow(img_filtered)
# plt.show()
#### 노이즈 제거 ####

#### 히스토그램 균일화 ####
# img_gray = cv2.imread("image02.jpeg", cv2.IMREAD_GRAYSCALE)
# img_equalized = cv2.equalizeHist(img_gray)

# cv2.imshow("org", img_gray)
# cv2.imshow("hist_equal", img_equalized)
# cv2.waitKey()
#### 히스토그램 균일화 ####

일반적으로 정사각형으로 만들면 화면비율이 깨짐

그런걸 방지하기 위해서 남는 부분은 다른 색으로 칠해버림

import matplotlib.pylab as plt
from PIL import Image

def expend2square(pil_img, background_color) :  # 배경이미지 크기계산
    width, heigth = pil_img.size
    
    if width == heigth :   # 이미 정사각형
        return pil_img
    
    elif width > heigth :  # 너비가 > 높이인 경우
        result = Image.new(pil_img.mode, (width, width), background_color)
        result.paste(pil_img, (0, (width - heigth) // 2))   # x 좌표는 0, y 좌표는 이미지 중앙에 이미지 붙임
        return result
    else :          # 높이가 > 너비인 경우
        result = Image.new(pil_img.mode, (heigth, heigth), background_color)
        result.paste(pil_img, ((heigth - width) //2,0))    # x 좌표는 이미지 중앙, y 좌표는 0 에 이미지 붙임
        return result
        

def resize_with_padding(pil_img, new_size, background_color) :  # 남는부분에 색칠하기
    img = expend2square(pil_img, background_color)
    img = img.resize((new_size[0], new_size[1]), Image.ANTIALIAS)
    
    return img
    
    
    
    
img = Image.open("./image01.jpeg")
img_new = resize_with_padding(img, (300,300), (0,0,255))  # 300, 300 : 사진 크기  # 0,0,255 : RGB 

plt.imshow(img)
plt.show()

plt.imshow(img_new)
plt.show()

XML Extensible Markup Language 어로, 데이터를 장하고 전하는 데 사용되는 마크업 언어입니다.

 

HTML과 매우 유사하 지만, XML은 데이터와 문서 구조를 설명하는 데 중점을 니다.

XML 스트 기반 형식이며, 데이터와 그 구조를 기하는 데 사용할 수 있는 여러가지 태그와 성을 제공합니다. 데이터는 요소(element)라고도 르는 태그를 사용하여 표시되며, 요소 는 (attribute) (value)을 가질 수 있습니다.

XML은 데이터를 계 구조로 구성할 수 있으, 다양한 소어 시스템 간에 데이터를 환하는 데 매우 유용합니다. , XML은 데이터의 검증  검색이 용이하며, 분의 로그래 어에서 XML 파 서를 지원하로 데이터를 게 처리할 수 있습니다.

 

 

import os 
import cv2
import matplotlib.pylab as plt
from xml.etree.ElementTree import parse

def xml_read(xml_path) :
    
    root = parse(xml_path).getroot()
    
    image_info = root.findall("image")
    
    for image in image_info :
        bbox = image.findall('box')
        # <image id="0" name="01.jpg" width="640" height="480">
        
        # image width height 
        image_width = image.attrib['width']
        image_heigth = image.attrib['height']
        
        # image name and path 
        image_name = image.attrib['name']
        image_name = os.path.join("./data/", image_name)
        
        # image read 
        image = cv2.imread(image_name)
        # image BGR -> RGB 
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
        for box_info in bbox :
            label = box_info.attrib['label']
            
            # 값 -> string 타입 
            xtl = box_info.attrib['xtl']
            ytl = box_info.attrib['ytl']
            xbr = box_info.attrib['xbr']
            ybr = box_info.attrib['ybr']
            
            # 소수점이 포함이라 바로 int 값 변환 불가 하여 float 변환 
            xtl_f = float(xtl)
            ytl_f = float(ytl)
            xbr_f = float(xbr)
            ybr_f = float(ybr)
            
            # float -> int 변환 
            xtl_i = int(xtl_f)
            ytl_i = int(ytl_f)
            xbr_i = int(xbr_f)
            ybr_i = int(ybr_f)
            
            print(xtl_i, ytl_i, xbr_i, ybr_i, label)
            ### xtl="468.94" ytl="92.01" xbr="640.00" ybr="340.46"
            
            ### 이미지 시각화 
            image = cv2.rectangle(image, (xtl_i, ytl_i), (xbr_i, ybr_i), (0,255,0), 2)
            
            ### 라벨 추가 
            image = cv2.putText(image, label, (xtl_i, ytl_i-10), 
                  cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)
         
        plt.imshow(image)
        plt.show()
    
xml_read("./data/annotations.xml")
 

xml to yolo format 변경하기 

 

import os 
import cv2
import matplotlib.pylab as plt
from xml.etree.ElementTree import parse

label_number_dict = {'cat':0, 'dog':1}

def xml_read(xml_path) :
    
    root = parse(xml_path).getroot()
    
    image_info = root.findall("image")
    
    for image in image_info :
        bbox = image.findall('box')
        # <image id="0" name="01.jpg" width="640" height="480">
        
        # image width height 
        image_width = image.attrib['width']
        image_heigth = image.attrib['height']
        
        # image name and path 
        image_name = image.attrib['name']
        image_name_temp = image_name
        image_name = os.path.join("./data/", image_name)
        
        # image read 
        image = cv2.imread(image_name)
        # image BGR -> RGB 
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
        for box_info in bbox :
            label = box_info.attrib['label']
            
            # 값 -> string 타입 
            xtl = box_info.attrib['xtl']
            ytl = box_info.attrib['ytl']
            xbr = box_info.attrib['xbr']
            ybr = box_info.attrib['ybr']
            
            # 소수점이 포함이라 바로 int 값 변환 불가 하여 float 변환 
            xtl_f = float(xtl)
            ytl_f = float(ytl)
            xbr_f = float(xbr)
            ybr_f = float(ybr)
            
            # float -> int 변환 
            x1_i = int(xtl_f)
            y1_i = int(ytl_f)
            x2_i = int(xbr_f)
            y2_i = int(ybr_f)
            
            ### xtl="468.94" ytl="92.01" xbr="640.00" ybr="340.46"
            
            # 이미지 사이즈가 필요 위에 있는 image_width, image_heigth 경우는 string 타입 형변환 필요 int 
            img_width_i = int(image_width)
            img_height_i = int(image_heigth)
            
            # Pascal_xyxy to YOlO center_x center_y yolo_w yolo_h 
            
            center_x = ((x2_i + x1_i)/(2*img_width_i))
            center_y = ((y2_i + y1_i)/(2*img_height_i))
            yolo_w = (x2_i - x1_i)/img_width_i
            yolo_h = (y2_i - y1_i)/img_height_i
                                    
            # file_name 
            image_name_temp = image_name_temp.replace('.jpg', '')
            
            # label cat, dog -> 0, 1 로 변경하기 
            label_number = label_number_dict[label]
            
            print("Pascal_xyxy to YOLO >> ", label_number,center_x, center_y, yolo_w, yolo_h)
    
            # 텍스트로 저장하기 
            with open(f"{image_name_temp}.txt", "a") as f:
                f.write(f"{label_number} {center_x} {center_y} {yolo_w} {yolo_h} \n")
    
xml_read("./data/annotations.xml")

Pascal_xyxy to YOLO >> 1 / 0.865625 / 0.45 / 0.26875 / 0.5166666666666667

Pascal_xyxy to YOLO >> 0 / 0.16171875 / 0.6041666666666666 / 0.3140625 / 0.44583333333333336

JSON(JavaScript Object Notation)은 경의 데이터 환 형식 입니다.

 

JSON은 사이 읽고 기에 용이하고, 기계가 분석하고 생성 하기도 쉬워 많이 사용됩니다.

특히 웹에서 데이터를 많이 사용되며, 분의 로그래어에서 JSON 형식을 다수 있습니다.

JSON은 키-값 쌍으로 이루어진 데이터 오브젝트를 장합니다. (key)는 문자이며, (value)은 문자, , 불리, , 객체 등이 수 있습니다. 이러한 데이터 오브젝트들은 중수 있어 복한 데이터도 표현할 수 있습니다.

 

 

import json

# json 파일을 가져와야합니다.
json_data_path ="./data/instances_default.json"

with open(json_data_path, 'r', encoding="utf-8") as j :  # 'r' read
    json_data = json.load(j)
    
print(f"json type : {type(json_data)}")
print("json_data : ", json_data )  # 키, 밸류로 반환

다차원 딕셔너리 형태라 원하는 정보를 위해선 한차원 더 들어가야합니다.

# 변수 선언
categories_info = json_data['categories']
# [{'id': 1, 'name': 'cat', 'supercategory': ''}, {'id': 2, 'name': 'dog', 'supercategory': ''}]

images_info = json_data['images']
# [{'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}]

 

 

위의 정보를 이용하여 이미지 시각화 실습

 

import json 
import os
import cv2
import matplotlib.pylab as plt

# json_path 경로 지정 
json_path = "./data/instances_default.json"

# json 읽기
with open(json_path, 'r', encoding='utf-8') as j : # 'r' : read
    json_data = json.load(j)
    
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']

# 라벨 딕셔너리 선언 
label_dict = {1: "cat", 2:"dog"}  # 0 은 배경임

for image_json in images_info : 
    print(image_json)
    # {'id': 1, 'width': 640, 'height': 480, 'file_name': '01.jpg', 'license': 0, 'flickr_url': '', 'coco_url': '', 'date_captured': 0}

    file_name = image_json['file_name']
    image_path = os.path.join("./data/", file_name)
    image_id = image_json['id']
    print(image_path)
    # ./data/01.jpg
    
    # image read 
    image = cv2.imread(image_path)
    # iamge BGR -> RGB 
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    # bbox info 
    for anno_json in annotations_info : 
        if image_id == anno_json['image_id'] :
            bbox = anno_json['bbox']
            # 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
            x = int(bbox[0])
            y = int(bbox[1])
            w = int(bbox[2])
            h = int(bbox[3])
            # 박스 좌표 확인 
            print("bbox 좌표 >> " , x, y, w, h)
            # bbox 좌표 >>  468 92 171 248
            # bbox 좌표 >>  3 183 200 214 
            
            
            # 박스 그리기 
            cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
            
            # 라벨 표시 
            category_id = anno_json['category_id']
            label_name = label_dict[category_id]
            print(label_name)
            # dog
            # cat 
            
            image = cv2.putText(image, label_name, (x, y-10),  # 위에 글자두려고 -10 
                  cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_AA)
            
            
    plt.imshow(image)
    plt.show()

 

 

json format -> Yolo format 으로 변경하고 텍스트 파일로 저장하기

import json 
import os
import cv2
import matplotlib.pylab as plt

# json_path 경로 지정 
json_path = "./data/instances_default.json"

# json 읽기
with open(json_path, 'r', encoding='utf-8') as j : 
    json_data = json.load(j)
    
category_info = json_data['categories']
images_info = json_data['images']
annotations_info = json_data['annotations']

# 라벨 딕셔너리 선언 
# 0 -> cat , 1 -> dog
label_dict = {1: 0, 2: 1}

for image_json in images_info : 
    print(image_json)
    file_name = image_json['file_name']
    image_path = os.path.join("./data/", file_name)
    image_id = image_json['id']
    print(image_path)
    print("file name ", file_name)
    
    # image read 
    image = cv2.imread(image_path)
    # iamge BGR -> RGB 
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    # image size 
    img_height, img_width, img_channel = image.shape
    
    # bbox info 
    for anno_json in annotations_info : 
        if image_id == anno_json['image_id'] :
            bbox = anno_json['bbox']
            # 좌표 변수에 박스 좌표 저장 (int 형 변환 이유 : cv2.rectangle 좌표 값은 int 형태만 가능)
            x = int(bbox[0])
            y = int(bbox[1])
            w = int(bbox[2])
            h = int(bbox[3])
            
            # 박스 그리기 
            cv2.rectangle(image, (x,y), (x+w, y+h), (0,255,0),2)
            
            # 라벨 표시 
            category_id = anno_json['category_id']
            label_number = label_dict[category_id]
            
            # xywh -> center_x, center_y, w, h 변경 하기 
            center_x = ((2*x + w)/(2*img_width))
            center_y = ((2*y + h)/(2*img_height))
            yolo_w = w/img_width
            yolo_h = h/img_height
            
            print("yolo 좌표 변경 값 >> ",label_number,center_x, center_y, yolo_w, yolo_h)
            # 이미지 명과 라벨 파일 명이 동일해야합니다. 
            # 위에 file_name 경우는 01.jpg 우리가 필요한것은 01 이라는 이름 입니다. 
            #file_name_tmep = os.path.splitext(file_name)[0]
            file_name_temp = file_name.replace(".jpg", "")
            
            # 텍스트 파일 쓰기 
        with open(f"{file_name_temp}.txt", "a") as f:  # "a" 는 덮어쓰기 말고 새로만듬
            f.write(f"{label_number} {center_x} {center_y} {yolo_w} {yolo_h} \n")

학습을  위해 대량의 사진을 가져오기 위한 코드

 

 

일반적으로 사진을 그냥 막 가져와버리면 정렬이 제대로 안됨

 

우선 사과라는 폴더안에 있는 사진들을 가져오고 싶을때

# os listdir
import os
# 이미지가 저장된 디렉토리 경로
img_dir = './사과/'

# 디렉토리 내 모든 파일 목록 가져오기
file_list = os.listdir(img_dir)
print(file_list)

# 단점 정렬 되지 않습니다.

 

sorted를 써도 마찬가지

# 만약 정렬 하고 싶다면 sort 함수 사용 
# os listdir
import os
# 이미지가 저장된 디렉토리 경로
img_dir = './사과/'

# 디렉토리 내 모든 파일 목록 가져오기
file_list = sorted(os.listdir(img_dir))
print(file_list)

 

 

import glob
import os 

file_list = glob.glob(os.path.join("./사과/", "*.jpg"))
print(file_list)

# 을 활용해야 제대로 정렬된 상태로 가져옴

 

 

폴더안의 폴더도 for문으로 가능함

#### os.walk 를 이용한 폴더에서 이미지 파일 가져오기 함수 구현

os.walk() 하위의 폴더들을 for문으로 탐색할 수 있게 해줍니다. 인자로 전달된 path에 대해서 다음 3개의 값이 있는 tuple을 넘겨줍니다.

- root : dir과 files가 있는 path
- dirs : root 아래에 있는 폴더들
- files : root 아래에 있는 파일들

 

def get_img_paths(root_path): # 하위에 있는 경로 모두 탐색
    file_paths = []
    for (path, dir, files) in os.walk(root_path):
        for file in files:
            ext = os.path.splitext(file)[-1].lower()
            formats = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.dng']
            if ext in formats:
                file_path = os.path.join(path, file)
                file_paths.append(file_path)
    return file_paths

file_paths = get_img_paths("./사과/")
print(file_paths)

# 정렬 하고 싶다면 natsort.natsorted 이용
# file_paths_sort = natsort.natsorted(file_paths)
# print(file_list_sort)

알고리즘은 컴퓨터 전 및 이미지 처리에서 주요한 역할을 합니다.

 

 

ORB (Oriented FAST and Rotated BRIEF):

 

 

1. FAST(FeaturesfromAcceleratedSegmentTest)기와BRIEF(BinaryRobustIndependent Elementary Features) 자의 합입니다.

2. FAST를 사하여 르게 특점을 하고, BRIEF를 사하여 특점 주변의 특설명합니다.

3. 회전에 변한 특설명을 제공합니다.
4. ORB
SIFT SURF더 빠르지만, 적으로 한 결과를 제공합니다.

 

import cv2

# 동영상 파일 열기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/vtest.avi")

# ORB 객체 생성
orb = cv2.ORB_create()

while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:
        break
        
    # 그레이스케일로 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 특징점 검출
    keypoints = orb.detect(gray, None)

    # 특징점 그리기
    frame = cv2.drawKeypoints(frame, keypoints, None, (0, 150, 220), flags=0)

    # 출력
    cv2.imshow("ORB", frame)
    if cv2.waitKey(30) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

를 쓰면 불필요한 특징점도 많이 나온다.

 

Mask를 활용하여 특징점 제거하기 2

 

 

import cv2
import numpy as np

# 동영상 파일 읽기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/vtest.avi")

# ORB 객체 생성
orb = cv2.ORB_create()

# 특징점 최소 크기 설정
min_keypoint_size = 10

# 중복 특징점 제거 기준거리
duplicate_threshold = 10

while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:
        break

    # 그레이스케일로 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 특징점 검출
    keypoints = orb.detect(gray, None)

    # 특징점 크기가 일정 크기 이상인 것만 남기기
    keypoints = [kp for kp in keypoints if kp.size > min_keypoint_size]  # 리스트 컴프리헨션(파이썬문법)

    # 중복된 특징점 제거
    mask = np.ones(len(keypoints), dtype=bool)  # 1차원 배열
    for i, kp1 in enumerate(keypoints):
        if mask[i]:
            for j, kp2 in enumerate(keypoints[i + 1:]):
                if (
                    mask[ i + j + 1]
                    and np.linalg.norm(np.array(kp1.pt) - np.array(kp2.pt)) < duplicate_threshold  # .pt : OpenCV의 KeyPoint 객체의 속성중 하나
                ):
                    mask[ i + j + 1] = False
    
    # kp1.pt와 kp2.pt는 각각 두 개의 키포인트 객체인 kp1과 kp2의 위치 좌표를 나타냅니다.
    """
 먼저, mask라는 길이가 keypoints의 길이와 동일한 불리언 배열을 생성합니다. 이 배열은 모든 원소를 True로 초기 화합니다.
그런 다음, keypoints 리스트를 반복하면서 현재 키포인트와 나머지 키포인트들 간의 거리를 계산하여 중복된 키포 인트를 확인합니다. 
중복된 키포인트인 경우에는 해당 키포인트에 해당하는 mask의 원소를 False로 설정합니다.
마지막으로, mask를 기반으로 중복되지 않은 키포인트들만을 새로운 리스트로 필터링하여 keypoints를 업데이트 합니다.
이를 통해 중복된 특징점을 제거하고 유니크한 특징점만을 남기는 작업을 수행합니다.
    
    """
    keypoints = [kp for i, kp in enumerate(keypoints) if mask[i]]

    # 특징점 그리기
    frame = cv2.drawKeypoints(frame, keypoints, None, (0, 200, 150), flags=0)

    cv2.imshow("ORB", frame)


    # 'q'를 누르면 종료
    if cv2.waitKey(60) == ord('q'):
        break

# 해제
cap.release()
cv2.destroyAllWindows()

 

 

 

 

알고리즘은 컴퓨터 전 및 이미지 처리에서 주요한 역할을 합니다.

SIFT (Scale-Invariant Feature Transform):

 

1. 크기 및 회전에 변한 특설명 알고리즘입니다.

2. 다양한 크기와 회전에서 특점을 하고,점 주변의 지역 특을 기합니다.

3. 점 간의 일기 위해 특점 기자를 사합니다.
4. SIFT
우 강력한 특및 일알고리즘으로 알져 있습니다.

 

 

import cv2

# 동영상 파읽 열기
cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/slow_traffic_small.mp4")

# sift 객체 생성
sift = cv2.SIFT_create()

while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:
        break

    # 그레이스케일로 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 특징점 검출
    keypoints, descriptors = sift.detectAndCompute(gray, None)

    # 특징점 그리기
    frame = cv2.drawKeypoints(frame, keypoints, None,
                              flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

    # 화면에 출력
    cv2.imshow("frame", frame)

    # 'q'를 누르면 종료
    if cv2.waitKey(60) == ord('q'):
        break

# 해제
cap.release()
cv2.destroyAllWindows()

 

 

개수제한 >>>

 

1. 이미지 대비 밝기 일정이상의 차이가 있을때만 보이게 하면서

2. 포인터를 수를 일정 수로 제한해서 포인터의 개수를 특정 객체에만 나타나게 설정

 

import cv2

cap = cv2.VideoCapture("MS/CV/0612 객체탐지,추적/data/slow_traffic_small.mp4")

# SIFT 객체 생성
sift = cv2.SIFT_create(contrastThreshold=0.02)   # 이미지 대비의 밝기 차이

# 특지점 개수 제한 설정
max_keypoints = 100  # 100개의 특징점만 검출

while True:
    # 프레임 읽기
    ret, frame = cap.read()
    if not ret:
        break

    # 그레이스케일로 변환
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 특징점 검출
    keypoints, descriptors = sift.detectAndCompute(gray, None)

    # 특징점 제한
    if len(keypoints) > max_keypoints:
        keypoints = sorted(keypoints, key=lambda x: -
                           x.response)[:max_keypoints]


    """
    keypoints = sorted(keypoints, key=lambda x: -x.response): 
    keypoints 리스트를 x.response를 기준으로 내림차순으로 정렬
    이는 키포인트의 response 값을 기준으로 정렬하겠다는 의미
    response 값이 큰 키포인트일수록 우선순위를 가지게 됩니다

    [:max_keypoints]: 정렬된 keypoints 리스트에서 처음부터 max_keypoints까지의 키포인트만 선택 
    이를 통해 최대 키포인트 수를 제한합니다.
    """
    
    
    # 특징점 그리기
    frame = cv2.drawKeypoints(frame, keypoints, None,
                              flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

    # 프레임 출력
    cv2.imshow("frame", frame)

    # 'q'를 누르면 종료
    if cv2.waitKey(60) == ord('q'):
        break

# 해제
cap.release()
cv2.destroyAllWindows()

 

 

+ Recent posts