반응형

Kiwipiepy를 이용해 한국어 형태소를 분석해 보자.

 

from kiwipiepy import Kiwi

kiwi = Kiwi()
kiwi.add_user_word("AI", "NNP")  # 사용자 단어 추가 예시

text = "안녕하세요. 저는 AI 언어 모델입니다."
result = kiwi.analyze(text)

# 출력 형태 확인
print(result)

print("-" * 30)

# 형태소와 품사 출력
for word in result[0][0]:
	print(f"{word.form}\t{word.tag}")

print("-" * 30)

# 명사만 출력
print("명사만 출력:")
for word in result[0][0]:
	if word.tag.startswith('N'):
		print(f"{word.form}\t{word.tag}")

nouns = [word.form for word in result[0][0] if word.tag.startswith('N')]
print("명사 리스트:", nouns)

print("-" * 30)

# 동사만 출력
print("동사만 출력:")
for word in result[0][0]:
	if word.tag.startswith('V'):
		print(f"{word.form}\t{word.tag}")

verbs = [word.form for word in result[0][0] if word.tag.startswith('V')]
print("동사 리스트:", verbs)

 

 

이번엔 간단한 Word Cloud 예제를 살펴보자.

 

from wordcloud import WordCloud
import matplotlib.pyplot as plt

text = "인공지능은 현대 기술의 핵심입니다.\
인공지능은 다양한 분야에서 활용되고 있으며,\
우리의 삶을 변화시키고 있습니다. 인공지능\
기술은 빠르게 발전하고 있으며, 미래에는 더욱\
중요한 역할을 할 것입니다."

# 워드클라우드 생성
wordcloud = WordCloud(font_path='malgun.ttf',\
width=640, height=480, max_words=100,\
background_color='white', colormap='hsv')\
.generate(text)

# 워드클라우드 시각화
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()

 

 

마지막으로 긴 텍스트에서 형태소 분석기를 이용해 명사를 추출하고 최다 빈도 명사 10개로 워드 클라우드를 생성해 보자.

 

from kiwipiepy import Kiwi
from wordcloud import WordCloud
from collections import Counter
import matplotlib.pyplot as plt

kiwi = Kiwi()

text = "《시간의 역사》(A Brief History of Time)는 스티븐 호킹에 의해 쓰여진 저명한 과학책으로\
1988년 벤탐 델 출판사에 의해 출판된 책이다. 이 책은 베스트셀러로 천 만 부 이상이 팔렸으며, 또한\
런던 선데이 타임즈에 베스트셀러로 4년 이상 랭크되었다. <시간의 역사>는 갈릴레이, 뉴턴, 아인슈타인\
등의 과거 과학자들의 우주에 대한 연구 내용을 핵심적으로 짚어주고, 우주가 대폭발에서 시작했다는\
빅뱅 이론, 블랙홀과 특이점에 대한 내용, 우주의 역사를 통해 우주의 미래와 종말을 전망한다. 이 책을\
통해 '시간'이라는 개념에 대해서도 새로운 인식을 하게 만들었다. 지구에서만 적용되는 물리적인 법칙이\
깨지거나 변화하는 우주 다른 공간에서는 우리가 쓰는 '시간'의 의미가 완전히 달라짐을 말해준다."
result = kiwi.analyze(text)

# 명사만 출력
# print("명사만 출력:")
# for word in result[0][0]:
# 	if word.tag.startswith('N'):
# 		print(f"{word.form} : {word.tag}")

# 명사 리스트 생성
nouns = [word.form for word in result[0][0] if word.tag.startswith('N')]
print("■ 명사 리스트:", nouns)

# 명사 빈도수 10위까지 출력
counts = Counter(nouns)
print("\n■ 명사 빈도수:", counts.most_common(10))

# 명사 워드 클라우드 생성
wordcloud = WordCloud(font_path='malgun.ttf', width=640, height=480, max_words=100,\
   background_color='white', colormap='hsv').generate_from_frequencies(counts)

# 워드 클라우드 시각화
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()

 

 

 

반응형
Posted by J-sean
:
반응형

파이썬 콘솔 환경에서 예쁘게 빛나는 크리스마스 트리를 만들어 보자.

 

import time
import random
import os

# Clear the console based on the operating system
os.system('cls' if os.name == 'nt' else 'clear')

# Define color codes
# '\033[0m': text and background colors reset
color_format = ['\033[31m', '\033[32m', '\033[33m','\033[34m', '\033[35m','\033[36m', '\033[37m', '\033[0m']

tree = [
    "      *      ",
    "     ***     ",
    "    *****    ",
    "   *******   ",
    "  *********  ",
    " *********** ",
    "*************",
    "      |      ",
    "      |      "
]

while True:
    time.sleep(0.5)    
    for line in tree:
        colored_line = ''.join(f"{random.choice(color_format)}{char}" if char == '*' \
                               else f"{color_format[-1]}{char}" for char in line)
        print(colored_line)
    print("\033[F" * 9, end='')  # Move cursor up nine lines

 

 

컬러 포멧으로 딕셔너리를 사용한 예는 아래 더보기를 클릭하자.

더보기

아래 코드도 같은 결과를 보여준다.

 

import time
import random
import os

# Clear the console based on the operating system
os.system('cls' if os.name == 'nt' else 'clear')

# Define color codes
color_format = {
    'RED': '\033[31m',
    'GREEN': '\033[32m',
    'YELLOW': '\033[33m',
    'BLUE': '\033[34m',
    'MAGENTA': '\033[35m',
    'CYAN': '\033[36m',
    'WHITE': '\033[37m',
    'RESET': '\033[0m'
}

tree = [
    "      *      ",
    "     ***     ",
    "    *****    ",
    "   *******   ",
    "  *********  ",
    " *********** ",
    "*************",
    "      |      ",
    "      |      "
]

print('{RED}Merry {BLUE}Christmas!!'.format(**color_format))
print(f"{color_format[random.choice(list(color_format.keys()))]}Happy New Year!!{color_format['RESET']}")

while True:
    time.sleep(0.5)
    for line in tree:
        colored_line = ''.join(f"{random.choice(list(color_format.values()))}{char}" if char == '*' \
                               else f"{color_format['RESET']}{char}" for char in line)
        print(colored_line)
    print("\033[F" * 9, end='')  # Move cursor up nine lines

 

 

반응형
Posted by J-sean
:
반응형

바이너리 파일을 읽고 유니코드 문자열을 찾아 수정해 보자.

 

Procmon64.exe
2.04MB

이 파일의 내용을 읽고 수정해 보자.

 

 

Procmon64.exe 파일의 0xF9560 위치에 'ProcM' 이라는 유니코드(UTF-16) 문자열이 있다.

 

import binascii

with open("Procmon64.exe", "rb") as f:
	f.seek(0xf9560) # 파일 포인터 이동
	data = f.read(10)
	print(f"Bytes: {data}")
	print(f"Hex: {binascii.b2a_hex(data).decode().upper()}")
	print(f"Unicode: {binascii.unhexlify(binascii.b2a_hex(data)).decode(encoding='utf-16', errors='ignore')}")
	print("File Pointer Position: " + hex(f.tell()).upper())  # 현재 파일 포인터 위치 출력

 

0xF9560위치에서 10바이트를 읽고 출력해 보자.

 

'ProcM' 문자열이 읽혀진다.

 

 

import binascii

with open("Procmon64.exe", "r+b") as f:
    f.seek(0xf9560) # 파일 포인터 이동
    pattern = "QrocM".encode(encoding="utf-16le").hex()
    f.write(bytes.fromhex(pattern))	

    f.seek(-10, 1)  # 현재 위치(1)에서 10바이트 앞으로 이동
    data = f.read(10)
    print(f"Bytes: {data}")
    print(f"Hex: {binascii.b2a_hex(data).decode().upper()}")
    print(f"Unicode: {binascii.unhexlify(binascii.b2a_hex(data)).decode(encoding='utf-16', errors='ignore')}")

 

'ProcM'을 'QrocM'으로 바꿔보자.

 

문자열이 'QrocM'으로 바뀌었다.

 

파일을 직접 확인해 보자.

 

 

import binascii

file_name = "Procmon64.exe"
pattern = "ProcM"
byte_sequence = pattern.encode(encoding="utf-16le")

def find_all_bytes(file_name, byte_sequence):
    with open(file_name, 'rb') as f:
        file_content = f.read()  # 파일 전체를 바이트열로 읽어옵니다.

    occurrences = []
    start_index = 0
    while True:
        try:
            # find() 메서드는 일치하는 위치의 인덱스를 반환합니다.
            index = file_content.find(byte_sequence, start_index)
            if index == -1:
                break  # 더 이상 일치하는 패턴이 없으면 루프를 종료합니다.
            occurrences.append(hex(index).upper())
            start_index = index + len(byte_sequence)  # 다음 검색 시작 위치를 갱신합니다.
        except ValueError:
            break

    return occurrences

positions = find_all_bytes(file_name, byte_sequence)

print(f"문자열 {pattern}({byte_sequence.hex().upper()})이(가) 발견된 위치:")
for idx, pos in enumerate(positions):
    print(f"{idx+1}. 오프셋 [{pos}]에서 발견됨.")

 

파일 전체에서 'ProcM' 문자열을 찾아보자.

 

5개의 'ProcM' 문자열이 발견되었다.

 

직접 확인해 보자. 5개의 같은 결과가 나온다.

 

 

import re

text = "The rain in Spain stays mainly in the plain.".encode(encoding="utf-16le")
print(f"UTF-16 Text: {text}")

matches = re.findall("ain".encode(encoding="utf-16le"), text)  # 대소문자 구분
print(matches)

matches = re.findall("Ain".encode(encoding="utf-16le"), text, re.IGNORECASE)  # 대소문자 무시
print(matches)

 

'PROCM', 'procm', 'Procm' 등 대소문자 구분없이 모든 문자열을 찾기 위해 파이썬 정규식 표현을 살펴보자.

 

코드 마지막에서 'Ain' 문자열을 대소문자 구분 없이 모두 찾았다.

 

import re

text = "The rain in Spain stays mainly in the plain.".encode(encoding="utf-16le")
pattern = "Ain".encode(encoding="utf-16le")
print(f"UTF-16 Text: {text}")
print(f"UTF-16 Pattern: {pattern}")

for idx, match in enumerate(re.finditer(pattern, text, re.IGNORECASE)):
    print(f"{idx+1}. {match.group()} found at byte offset: {match.start()}")

 

이번엔 finditer()로 문자열의 위치까지 정확히 찾아보자.

 

찾은 문자열의 위치가 표시된다. (문자 하나는 2바이트)

 

 

import binascii
import re

file_name = "Procmon64.exe"
pattern = "ProcM"
byte_sequence = pattern.encode(encoding="utf-16le")

with open(file_name, 'rb') as f:
    file_content = f.read()
    print(f"Searching for pattern: {pattern}")

    # Find all occurrences of the byte sequence in the file content
    for idx, match in enumerate(re.finditer(byte_sequence, file_content, re.IGNORECASE)):
        print(f"{idx+1:2}. {binascii.unhexlify(binascii.b2a_hex(match.group())).decode(encoding='utf-16', errors='ignore')} \
        found at byte offset: {hex(match.start()).upper()}")

 

위 결과를 바탕으로 'ProcM' 문자열을 대소문자 구분 없이 찾아보자.

 

'ProcM' 문자열이 대소문자 구분없이 모두 찾아졌다.

 

직접 확인해 봐도 40개의 결과가 표시된다.

 

import binascii
import re

def replace_pattern_in_file(file_name, pattern, replacement):
    byte_sequence = pattern.encode(encoding="utf-16le")
    with open(file_name, 'r+b') as f:
        file_content = f.read()
        print(f"Searching for pattern: {pattern}")

        # Find all occurrences of the byte sequence in the file content
        # Case-sensitive search
        for idx, match in enumerate(re.finditer(byte_sequence, file_content)):
            print(f"{idx+1:2}. {binascii.unhexlify(binascii.b2a_hex(match.group())).decode(encoding='utf-16', errors='ignore')} found at byte offset: {hex(match.start()).upper()}")
            
            f.seek(match.start())
            f.write(replacement.encode(encoding="utf-16le"))
            print(f"   => Replaced with: {replacement} at byte offset: {hex(match.start()).upper()}")

file_name = "Procmon64.exe"
pattern = "ProcM"

replace_pattern_in_file(file_name, pattern, "Q")

 

파일에서 대소문자를 구분해 문자열을 모두 찾아 바꾸는 함수를 작성했다.

함수에 파일 이름, 찾을 문자열, 바꿀 문자열을 인자로 주고 실행한다.

 

모든 'ProcM'이 'QrocM'으로 바뀌었다.

 

반응형
Posted by J-sean
:

Windows Mutex for Python

Python 2025. 2. 26. 11:28 |
반응형

파이썬에서 윈도우 뮤텍스를 사용해 보자.

 

아래 링크에서 namedmutex.py를 다운받고 파이썬 프로젝트에 포함시킨다.

namedmutex

namedmutex.py
0.00MB

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import namedmutex
#from time import sleep
 
# with namedmutex.NamedMutex('MyMutex'):
#     while True:
#         sleep(1)
#         print("Running")
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(2):
    print("Mutex not acquired.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Threading;
 
public class Program
{
    public static void Main()
    {
        Mutex mutex = new Mutex(false"MyMutex");
        if (!mutex.WaitOne(2000))
        {
            Console.WriteLine("Signal not received.");
            mutex.Close();
            return;
        }
 
        Console.WriteLine("Waiting...");
        Console.ReadLine();
 
        mutex.ReleaseMutex();
        mutex.Close();
    }
}
 

 

위 파이썬 프로그램, C# 프로그램 중 중복을 포함하여 아무거나 두 개(두 번) 실행시켜 보면 MyMutex의 상황에 따라 실행 가능 여부를 확인 할 수 있다.

 

이번엔 뮤텍스를 사용해 프로그램의 중복 실행을 방지하는 코드를 살펴보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import namedmutex
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(0):
    print("Program is running already.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

위 프로그램을 실행한 상태에서 또  실행하면 두 번째 실행한 프로그램은 메세지가 출력되고 종료된다.

 

반응형
Posted by J-sean
:
반응형

C와 Python 프로그램간 이미지 데이터를 공유해 보자.

 

1) 파이썬 프로그램 데이터를 C 프로그램에 공유

mmap

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time
import mmap
import cv2
 
frame = cv2.imread("image.jpg", cv2.IMREAD_COLOR)
h, w, c = frame.shape
buffer_size = h * w * c
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:
    mm.write(frame.tobytes())
 
    while True:
        time.sleep(1000)  # Sleep to prevent busy waiting.
finally:
    mm.close()
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <opencv2/opencv.hpp>
#include <Windows.h>
 
int main() {
    int height = 495;
    int width = 396;
    int channels = 3;
    int buffersize = height * width * channels;
 
    byte* buffer = new byte[buffersize];
    memset(buffer, 0, buffersize);
 
    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;
 
    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 00, buffersize);
    if (PtrInFile == NULL)
        return -1;
 
    memcpy(buffer, PtrInFile, buffersize);
 
    cv::Mat image = cv::Mat(height, width, CV_8UC3, buffer);
    if (image.empty())
        return -1;
 
    // 사용할 Mat이 이미 존재한다면 아래처럼 memcpy()를 사용할 수도 있다.
    //cv::Mat image(height, width, CV_8UC3); // 이미 존재하는 Mat
    //memcpy(image.data, buffer, buffersize); // buffer 사용하지 않고 메모리에서 image.data로 직접 복사해도 된다.
 
    cv::imshow("image", image);
    cv::waitKey(0);
        
    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    delete[] buffer;
 
    return 0;
}
 

 

 

파이썬 프로그램을 먼저 실행하고 C 프로그램을 실행한다.

 

 

2) C 프로그램 데이터를 파이썬 프로그램에 공유

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <opencv2/opencv.hpp>
#include <Windows.h>
 
int main() {
    cv::Mat image = cv::imread("image.jpg");
    if (image.empty())
        return -1;
 
    int height = image.rows;
    int width = image.cols;
    int channels = image.channels();
    int buffersize = height * width * channels;
 
    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;
 
    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 00, buffersize);
    if (PtrInFile == NULL)
        return -1;
 
    memcpy(PtrInFile, image.data, buffersize);
    // 버퍼를 사용하지 않고 바로 메모리에 데이터 복사.
        
    int a;
    std::cin >> a;
    // 대기
 
    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    
    return 0;
}
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import mmap
import numpy as np
import cv2
 
height = 495
width = 396
channels = 3
buffer_size = height * width * channels
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:    
    buffer = mm.read(buffer_size)
    image_arr = np.frombuffer(buffer, np.ubyte)
    image = image_arr.reshape(height, width, channels)
    
    cv2.imshow("image", image)
    cv2.waitKey(0)
finally:
    mm.close()
    cv2.destroyAllWindows()
 

 

결과는 같다.

 

※ 참고

2025.02.16 - [OpenCV] - C# and Python OpenCV Image Data Share (Memory Mapped File)

 

반응형
Posted by J-sean
:
반응형

C#과 Python 프로그램간 이미지 데이터를 공유해 보자.

 

1) Python 프로그램 데이터를 C# 프로그램에 공유.

mmap

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import time
import mmap
import cv2
 
frame = cv2.imread("image.jpg", cv2.IMREAD_COLOR)
h, w, c = frame.shape
buffer_size = h * w * c
 
# 3개의 4바이트(12바이트) 데이터를 위한 추가 공간 확보
#buffer_size = h * w * c + 12
 
# Open a memory-mapped file.
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:
    # 만약 3개의 4바이트 데이터를 저장하고 싶다면 아래와
    # 같이 한다.
    #mm.write(h.to_bytes(4))
    #mm.write(w.to_bytes(4))
    #mm.write(c.to_bytes(4))
 
    mm.write(frame.tobytes())
    
    # Keep the Python script running for demonstration.
    while True:
        time.sleep(1000)  # Sleep to prevent busy waiting.
finally:
    mm.close()
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using OpenCvSharp;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
 
public class Program
{
    public static void Main()
    {
        int width = 396;
        int height = 495;
        int channels = 3;
 
        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("MySharedMemory"))
        {
            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
            {
                byte[] buffer = new byte[width * height * channels];
                accessor.ReadArray(0, buffer, 0, buffer.Length);
 
                // 만약 buffer 앞 부분에 3개의 4바이트 int 데이터가 저장되어 있다면 아래와 같이 읽는다.
                // (물론 위에서 buffer[] 생성시 12바이트의 추가 공간 확보가 필요하다)
                //int h = ((buffer[0] << 24) +  (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3]));
                //Console.WriteLine(h);
                //int w = ((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
                //Console.WriteLine(w);
                //int c = ((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11]));
                //Console.WriteLine(c);
 
                // When buffer[] represents encoded image data (ex. JPEG, PNG, etc.), you can use
                // FromImageData or ImDecode.
                //buffer = System.IO.File.ReadAllBytes("image.jpg");
                //Mat mat = Mat.FromImageData(buffer, ImreadModes.Color);                
                //Mat mat = Cv2.ImDecode(buffer, ImreadModes.Color);
 
                // When buffer[] represens pixel data (BGRBGR...) , you need to hard-code copying operation.
                //Mat mat = new Mat(height, width, MatType.CV_8UC3);
                //Mat.Indexer<Vec3b> indexer = mat.GetGenericIndexer<Vec3b>();
                //for (int y = 0; y < height; y++)
                //{
                //    for (int x = 0; x < width; x++)
                //    {
                //        int pos = y * width * channels + x * channels;
                //        byte blue = buffer[pos + 0];
                //        byte green = buffer[pos + 1];
                //        byte red = buffer[pos + 2];
                //        Vec3b newValue = new Vec3b(blue, green, red);
                //        indexer[y, x] = newValue;
                //    }
                //}
 
                // If buffer[]'s step length is equal to the Mat's, there is a more effective way.
                Mat mat = new Mat(height, width, MatType.CV_8UC3);
                int length = height * width * channels;
                Marshal.Copy(buffer, 0, mat.Data, length);
 
                Cv2.ImShow("image", mat);
                Cv2.WaitKey(0);
                Cv2.DestroyAllWindows();
            }
        }
    }
}
 

 

 

Python 프로그램을 먼저 실행하고 C# 프로그램을 실행한다.

 

2) C# 프로그램 데이터를 Python 프로그램에 공유.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using OpenCvSharp;
 
public class Program
{
    public static void Main()
    {   
        Mat image = Cv2.ImRead("image.jpg", ImreadModes.Color);
        int width = image.Width;
        int height = image.Height;
        int channels = image.Channels();
        int buffer_size = width * height * channels;
 
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("MySharedMemory", buffer_size))
        {
            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
            {
                byte[] buffer = new byte[buffer_size];
                Marshal.Copy(image.Data, buffer, 0, buffer_size);
                accessor.WriteArray<byte>(0, buffer, 0, buffer_size);
            }
            
            Console.WriteLine("waiting...");
            Console.ReadLine();
        }        
    }
}
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import mmap
import numpy as np
import cv2
 
height = 495
width = 396
channels = 3
buffer_size = height * width * channels
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:    
    buffer = mm.read(buffer_size)
    image_arr = np.frombuffer(buffer, np.ubyte)
    image = image_arr.reshape(height, width, channels)
    
    cv2.imshow("image", image)
    cv2.waitKey(0)
finally:
    mm.close()
    cv2.destroyAllWindows()
 

 

결과는 같다.

 

※ 참고

2025.02.23 - [OpenCV] - C and Python OpenCV Image Data Share (Memory Mapped File)

 

반응형
Posted by J-sean
:
반응형

PyQt를 이용해 OpenCV 이미지를 출력해 보자.

 

디자이너에서 Dialog에 Label을 하나 배치하고 사이즈를 충분히 크게 한다. (test.ui)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys
import cv2
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import uic
 
myui = uic.loadUiType("test.ui")
 
class MyApp(QtWidgets.QWidget, myui[0]):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
 
        # 1) QtWidgets.QGraphicsView()에 이미지 출력하기
        # pixmap = QtGui.QPixmap()
        # pixmap.load("palvin.jpg")
        # scene = QtWidgets.QGraphicsScene()
        # scene.addPixmap(pixmap)
        # self.graphicsView.setScene(scene)
 
        # 2) QtWidgets.QGraphicsView()에 OpenCV 이미지 출력하기
        # img = cv2.imread("palvin.jpg")
        # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # h, w, c = img.shape
        # qimg = QtGui.QImage(img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
        # pixmap = QtGui.QPixmap.fromImage(qimg)
        # scene = QtWidgets.QGraphicsScene()
        # scene.addPixmap(pixmap)
        # self.graphicsView.setScene(scene)
 
        # QtWidgets.Label에 OpenCV 이미지 출력하기
        img = cv2.imread("palvin.jpg")
        img = cv2.resize(img, (self.label.size().width(), self.label.size().height()))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        h, w, c = img.shape
        qimg = QtGui.QImage(img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
        pixmap = QtGui.QPixmap.fromImage(qimg)
        self.label.setPixmap(pixmap)
 
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myWindow = MyApp()
    myWindow.show()
   app.exec_()
 

 

소스를 입력하고 실행한다.

 

Label 사이즈에 맞게 이미지가 조절되었다.

 

이번엔 GraphicsView를 사용해 보자. 위 소스에서 1번이나 2번 주석을 해제한다.

1, 2번 주석부분의 소스는 이미지 크기를 조절하지 않는다.

 

Label은 삭제하고 Graphics View를 배치하고 크기를 조정한다.

 

이미지가 Graphics View보다 크지만 스크롤바가 표시된다.

 

Widget 없이 Dialog에 직접 이미지를 출력할 수 도 있다. Dialog만 남기고 모두 삭제한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import sys
import cv2
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import uic
 
myui = uic.loadUiType("test.ui")
 
class MyApp(QtWidgets.QWidget, myui[0]):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
 
        self.img = cv2.imread("palvin.jpg")        
        self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB)
        h, w, c = self.img.shape
        h, w = int(h/6), int(w/6)        
        self.img = cv2.resize(self.img, (w, h))
        self.qimg = QtGui.QImage(self.img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
    
    def paintEvent(self, e):
        qp = QtGui.QPainter(self)
        self.drawCVImage(qp)
 
    def drawCVImage(self, qp):
        qp.drawImage(1010self.qimg)
        
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myWindow = MyApp()
    myWindow.show()
   app.exec_()
 

 

소스를 입력하고 실행한다.

 

Dialog에 직접 이미지가 출력된다.

 

반응형
Posted by J-sean
:
반응형

C#에서 파이썬 스크립트를 실행해 보자.

 

1
2
3
4
5
import sys
 
print(sys.argv[0])
if len(sys.argv) > 1:
    print(sys.argv[1])
 

 

우선 위와 같은 파이썬 스크립트(script.py)를 하나 작성하고 저장한다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Diagnostics;
class CSTest
{
    public static void Main()
    {
        Process process = new Process();
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "script.py abc";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
 
        process.Start();
        process.WaitForExit();
 
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
 
        Console.WriteLine("■ Output:");
        Console.WriteLine(output);
        Console.WriteLine("■ Error:");
        Console.WriteLine(error);
    }
}
 

 

C# 코드를 작성하고 빌드한다.

 

실행하면 파이썬 스크립트의 결과가 출력된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Diagnostics;
 
class CSTest
{
    public static void Main()
    {
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.CreateNoWindow = true;
 
        process.Start();
        process.StandardInput.WriteLine("dir/w");
        process.StandardInput.WriteLine("time");
        process.StandardInput.Flush();
        process.StandardInput.Close();
        process.WaitForExit();
 
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
 
        Console.WriteLine("■ Output:");
        Console.WriteLine(output);
        Console.WriteLine("■ Error:");
        Console.WriteLine(error);
    }
}
 

 

파이썬 스크립트를 가상환경에서 실행해야 하거나 복잡한 명령을 차례대로 실행해야 하는 경우 위 코드처럼 cmd를 먼저 실행하고 다른 명령을 순서대로 실행한다.

 

 

반응형
Posted by J-sean
: