Showing
16 changed files
with
363 additions
and
0 deletions
source code/pad_data/.gitignore
0 → 100644
1 | +/juno |
source code/pad_data/.idea/dataset.iml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<module type="PYTHON_MODULE" version="4"> | ||
3 | + <component name="NewModuleRootManager"> | ||
4 | + <content url="file://$MODULE_DIR$" /> | ||
5 | + <orderEntry type="inheritedJdk" /> | ||
6 | + <orderEntry type="sourceFolder" forTests="false" /> | ||
7 | + </component> | ||
8 | + <component name="TestRunnerService"> | ||
9 | + <option name="PROJECT_TEST_RUNNER" value="pytest" /> | ||
10 | + </component> | ||
11 | +</module> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
source code/pad_data/.idea/misc.xml
0 → 100644
source code/pad_data/.idea/modules.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ProjectModuleManager"> | ||
4 | + <modules> | ||
5 | + <module fileurl="file://$PROJECT_DIR$/.idea/dataset.iml" filepath="$PROJECT_DIR$/.idea/dataset.iml" /> | ||
6 | + </modules> | ||
7 | + </component> | ||
8 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
source code/pad_data/.idea/vcs.xml
0 → 100644
source code/pad_data/.idea/workspace.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ChangeListManager"> | ||
4 | + <list default="true" id="7a60ea4e-0e66-4fb3-9f90-7b3a4b35774b" name="Default Changelist" comment=""> | ||
5 | + <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||
6 | + <change beforePath="$PROJECT_DIR$/change.py" beforeDir="false" afterPath="$PROJECT_DIR$/change.py" afterDir="false" /> | ||
7 | + </list> | ||
8 | + <option name="SHOW_DIALOG" value="false" /> | ||
9 | + <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||
10 | + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | ||
11 | + <option name="LAST_RESOLUTION" value="IGNORE" /> | ||
12 | + </component> | ||
13 | + <component name="FileTemplateManagerImpl"> | ||
14 | + <option name="RECENT_TEMPLATES"> | ||
15 | + <list> | ||
16 | + <option value="Python Script" /> | ||
17 | + </list> | ||
18 | + </option> | ||
19 | + </component> | ||
20 | + <component name="Git.Settings"> | ||
21 | + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> | ||
22 | + </component> | ||
23 | + <component name="ProjectId" id="1s952kK9rpTSw6LkimeqRC1dJQ8" /> | ||
24 | + <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> | ||
25 | + <component name="ProjectViewState"> | ||
26 | + <option name="hideEmptyMiddlePackages" value="true" /> | ||
27 | + <option name="showLibraryContents" value="true" /> | ||
28 | + </component> | ||
29 | + <component name="PropertiesComponent"> | ||
30 | + <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> | ||
31 | + <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> | ||
32 | + <property name="last_opened_file_path" value="$PROJECT_DIR$/file" /> | ||
33 | + </component> | ||
34 | + <component name="RecentsManager"> | ||
35 | + <key name="CopyFile.RECENT_KEYS"> | ||
36 | + <recent name="$PROJECT_DIR$/file" /> | ||
37 | + <recent name="C:\Users\이준호\Desktop\nomad\dataset\juno\data" /> | ||
38 | + </key> | ||
39 | + </component> | ||
40 | + <component name="RunManager" selected="Python.change"> | ||
41 | + <configuration name="change" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | ||
42 | + <module name="dataset" /> | ||
43 | + <option name="INTERPRETER_OPTIONS" value="" /> | ||
44 | + <option name="PARENT_ENVS" value="true" /> | ||
45 | + <envs> | ||
46 | + <env name="PYTHONUNBUFFERED" value="1" /> | ||
47 | + </envs> | ||
48 | + <option name="SDK_HOME" value="" /> | ||
49 | + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> | ||
50 | + <option name="IS_MODULE_SDK" value="true" /> | ||
51 | + <option name="ADD_CONTENT_ROOTS" value="true" /> | ||
52 | + <option name="ADD_SOURCE_ROOTS" value="true" /> | ||
53 | + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/change.py" /> | ||
54 | + <option name="PARAMETERS" value="" /> | ||
55 | + <option name="SHOW_COMMAND_LINE" value="false" /> | ||
56 | + <option name="EMULATE_TERMINAL" value="false" /> | ||
57 | + <option name="MODULE_MODE" value="false" /> | ||
58 | + <option name="REDIRECT_INPUT" value="false" /> | ||
59 | + <option name="INPUT_FILE" value="" /> | ||
60 | + <method v="2" /> | ||
61 | + </configuration> | ||
62 | + <configuration name="main" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true"> | ||
63 | + <module name="dataset" /> | ||
64 | + <option name="INTERPRETER_OPTIONS" value="" /> | ||
65 | + <option name="PARENT_ENVS" value="true" /> | ||
66 | + <envs> | ||
67 | + <env name="PYTHONUNBUFFERED" value="1" /> | ||
68 | + </envs> | ||
69 | + <option name="SDK_HOME" value="" /> | ||
70 | + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> | ||
71 | + <option name="IS_MODULE_SDK" value="true" /> | ||
72 | + <option name="ADD_CONTENT_ROOTS" value="true" /> | ||
73 | + <option name="ADD_SOURCE_ROOTS" value="true" /> | ||
74 | + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" /> | ||
75 | + <option name="PARAMETERS" value="" /> | ||
76 | + <option name="SHOW_COMMAND_LINE" value="false" /> | ||
77 | + <option name="EMULATE_TERMINAL" value="false" /> | ||
78 | + <option name="MODULE_MODE" value="false" /> | ||
79 | + <option name="REDIRECT_INPUT" value="false" /> | ||
80 | + <option name="INPUT_FILE" value="" /> | ||
81 | + <method v="2" /> | ||
82 | + </configuration> | ||
83 | + <recent_temporary> | ||
84 | + <list> | ||
85 | + <item itemvalue="Python.change" /> | ||
86 | + <item itemvalue="Python.main" /> | ||
87 | + </list> | ||
88 | + </recent_temporary> | ||
89 | + </component> | ||
90 | + <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> | ||
91 | + <component name="TaskManager"> | ||
92 | + <task active="true" id="Default" summary="Default task"> | ||
93 | + <changelist id="7a60ea4e-0e66-4fb3-9f90-7b3a4b35774b" name="Default Changelist" comment="" /> | ||
94 | + <created>1620271759246</created> | ||
95 | + <option name="number" value="Default" /> | ||
96 | + <option name="presentableId" value="Default" /> | ||
97 | + <updated>1620271759246</updated> | ||
98 | + </task> | ||
99 | + <servers /> | ||
100 | + </component> | ||
101 | + <component name="Vcs.Log.Tabs.Properties"> | ||
102 | + <option name="TAB_STATES"> | ||
103 | + <map> | ||
104 | + <entry key="MAIN"> | ||
105 | + <value> | ||
106 | + <State /> | ||
107 | + </value> | ||
108 | + </entry> | ||
109 | + </map> | ||
110 | + </option> | ||
111 | + </component> | ||
112 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
source code/pad_data/.vs/dataset/v16/.suo
0 → 100644
No preview for this file type
source code/pad_data/.vs/slnx.sqlite
0 → 100644
No preview for this file type
source code/pad_data/README.md
0 → 100644
1 | +## Capstone Design: customData | ||
2 | + | ||
3 | +### 🌈 customData 소개 | ||
4 | +``` | ||
5 | +customData는 0 ~ 9 범위의 숫자로 이루어진 데이터셋 입니다. | ||
6 | +데이터를 수집한 방법은 다음과 같습니다 | ||
7 | +``` | ||
8 | +- iPad를 이용하여 `0 ~ 9` 범위의 숫자를 사람들에게 직접 기록을 부탁하였습니다. | ||
9 | +- `25~27살` 남자 5명, `20~24살` 여자 5명에게 데이터를 받았습니다. | ||
10 | +- 받은 데이터를 가공하여 저장하고, 거기에 `blur` `color` `synthesis` 를 적용하였습니다. | ||
11 | +- 현재 숫자당 약 1,200 여개의 데이터가 존재합니다. | ||
12 | + | ||
13 | +<br/> | ||
14 | + | ||
15 | +### 👨🏻💻 OpenCV 를 이용한 customDataset 만들기 | ||
16 | +1. 배경색 변경하기 | ||
17 | + ```python | ||
18 | + def coloring(num, source) | ||
19 | + ``` | ||
20 | + | ||
21 | +2. 이미지에 noise 추가하기 (blur 처리 등) | ||
22 | + ```python | ||
23 | + def bluring(num, source) | ||
24 | + ``` | ||
25 | + | ||
26 | +3. 다른 이미지와 합성하기(원고지 등을 합성하여 배경으로 사용) | ||
27 | + ```python | ||
28 | + def synthesis(num, source, background) | ||
29 | + ``` | ||
30 | +<br/> | ||
31 | + | ||
32 | +### 🙆🏻♂️ How to use | ||
33 | +- `filename`에 원본 이미지 경로를 기입합니다. | ||
34 | +- 배경 합성시엔, `background`에 원본 배경 이미지 경로를 기입합니다. | ||
35 | +- `change.py` 파일을 실행합니다. | ||
36 | +```python | ||
37 | + python3 change.py # 를 통해 실행합니다 | ||
38 | +``` |
source code/pad_data/change.py
0 → 100644
1 | +import numpy as np | ||
2 | +import matplotlib.pyplot as plt | ||
3 | +import cv2 | ||
4 | +import os | ||
5 | + | ||
6 | +background = ' ' # put background.png's location | ||
7 | + | ||
8 | +def bluring(num, source): | ||
9 | + img = cv2.imread(source) | ||
10 | + kernel = np.ones((5, 5), np.float32)/25 | ||
11 | + blur = cv2.filter2D(img, -1, kernel) | ||
12 | + cv2.imshow("blur", blur) | ||
13 | + cv2.waitKey(0) | ||
14 | + cv2.destroyAllWindows() | ||
15 | + # cv2.imwrite(f"./juno/bluring/{num}/{source.split('/')[4].split('.')[0]}.png", blur) | ||
16 | + | ||
17 | +def coloring(num, source): | ||
18 | + img = cv2.imread(source) | ||
19 | + yuv_img = cv2.cvtColor(img, cv2.COLOR_BGR2YUV) | ||
20 | + | ||
21 | + cv2.imshow('yuv img', yuv_img) # color rgb -> bgr | ||
22 | + cv2.waitKey(0) | ||
23 | + cv2.destroyAllWindows() | ||
24 | + | ||
25 | + # color_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | ||
26 | + # cv2.imshow('color img', color_img) | ||
27 | + # cv2.waitKey(0) | ||
28 | + # cv2.destroyAllWindows() | ||
29 | + | ||
30 | + # cv2.imwrite(f"./juno/coloring/{num}/{source.split('/')[4].split('.')[0]}.png", yuv_img) | ||
31 | + | ||
32 | +def rotate(num, source): | ||
33 | + image = cv2.imread(source) | ||
34 | + # 행과 열 정보만 저장합니다. | ||
35 | + height, width = image.shape[:2] | ||
36 | + | ||
37 | + M = cv2.getRotationMatrix2D((width / 2, height / 2), 90, 0.5) | ||
38 | + dst = cv2.warpAffine(image, M, (width, height)) | ||
39 | + result = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB) | ||
40 | + cv2.imshow('rotate', result) | ||
41 | + cv2.waitKey(0) | ||
42 | + cv2.destroyAllWindows() | ||
43 | + # cv2.imwrite(f"./juno/rotate/{num}/{source.split('/')[4].split('.')[0]}.png", result) | ||
44 | + | ||
45 | + | ||
46 | +def synthesis(num, source, background): | ||
47 | + background_image = cv2.imread(background) | ||
48 | + background_resize = cv2.resize(background_image, dsize=(28, 28), interpolation=cv2.INTER_AREA) | ||
49 | + # image resize 확인 | ||
50 | + cv2.imshow('background_resize', background_resize) | ||
51 | + cv2.waitKey(0) | ||
52 | + | ||
53 | + # image load | ||
54 | + source_image = cv2.imread(source) | ||
55 | + result = cv2.add(source_image, background_resize) | ||
56 | + cv2.imshow('synthesis',result) | ||
57 | + cv2.waitKey(0) | ||
58 | + cv2.destroyAllWindows() | ||
59 | + # cv2.imwrite(f"./juno/synthesis6/{num}/{source.split('/')[4].split('.')[0]}.png", result) | ||
60 | + | ||
61 | +for i in range(10): | ||
62 | + file_dir = f"./juno/data/{i}" | ||
63 | + file_list = os.listdir(file_dir) | ||
64 | + for file in file_list: | ||
65 | + pass | ||
66 | + # coloring(i, f"{file_dir}/{file}") | ||
67 | + # bluring(i, f"{file_dir}/{file}") | ||
68 | + # synthesis(i, f"{file_dir}/{file}", background) |
source code/pad_data/file/9.png
0 → 100644
441 Bytes
source code/pad_data/file/background_1.png
0 → 100644
8.05 KB
source code/pad_data/main.py
0 → 100644
1 | +import cv2 | ||
2 | +import os | ||
3 | +import numpy as np | ||
4 | + | ||
5 | +filenames = ['13.jpg', '14.jpg', '15.jpg'] | ||
6 | + | ||
7 | +def generate_dataset(filename): | ||
8 | + src = cv2.imread(filename, cv2.IMREAD_GRAYSCALE) # 그레이 스케일로 변환 | ||
9 | + src = cv2.resize(src, (int(src.shape[1] / 5), int(src.shape[0] / 5))) # 이미지의 크기가 워낙 크기 때문에 5분의1로 줄여서 확인 | ||
10 | + cv2.imshow('gray', src) | ||
11 | + k = cv2.waitKey(0) | ||
12 | + cv2.destroyAllWindows() | ||
13 | + | ||
14 | + src = src[0:src.shape[0] - 10, 15:src.shape[1] - 25] # 양 옆의 노이즈를 제거 | ||
15 | + ret, binary = cv2.threshold(src, 170, 255, cv2.THRESH_BINARY_INV) # 영상 이진화 | ||
16 | + | ||
17 | + cv2.imshow('binary', binary) | ||
18 | + k = cv2.waitKey(0) | ||
19 | + cv2.destroyAllWindows() | ||
20 | + | ||
21 | + # binary = cv2.morphologyEx(binary , cv2.MORPH_OPEN , cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2)), iterations = 2) | ||
22 | + # cv2.imshow('binary',binary) | ||
23 | + # k = cv2.waitKey(0) | ||
24 | + # cv2.destroyAllWindows() | ||
25 | + | ||
26 | + contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 외곽선 검출 | ||
27 | + color = cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR) # 이진화 이미지를 color이미지로 복사(확인용) | ||
28 | + cv2.drawContours(color, contours, -1, (0, 255, 0), 3) # 초록색으로 외곽선을 그려준다. | ||
29 | + | ||
30 | + # 리스트연산을 위해 초기변수 선언 | ||
31 | + bR_arr = [] | ||
32 | + digit_arr = [] | ||
33 | + digit_arr2 = [] | ||
34 | + count = 0 | ||
35 | + | ||
36 | + # 검출한 외곽선에 사각형을 그려서 배열에 추가 | ||
37 | + for i in range(len(contours)): | ||
38 | + bin_tmp = binary.copy() | ||
39 | + x, y, w, h = cv2.boundingRect(contours[i]) | ||
40 | + bR_arr.append([x, y, w, h]) | ||
41 | + | ||
42 | + bR_arr = sorted(bR_arr, key=lambda num: num[0], reverse=False) | ||
43 | + | ||
44 | + print(bR_arr[:5]) | ||
45 | + print(len(bR_arr)) | ||
46 | + | ||
47 | + # 작은 노이즈데이터 버림,사각형그리기, 10개씩 리스트로 다시 묶어서 저장 | ||
48 | + for x, y, w, h in bR_arr: | ||
49 | + tmp_y = bin_tmp[y - 2:y + h + 2, x - 2:x + w + 2].shape[0] | ||
50 | + tmp_x = bin_tmp[y - 2:y + h + 2, x - 2:x + w + 2].shape[1] | ||
51 | + if tmp_x and tmp_y > 10: | ||
52 | + count += 1 | ||
53 | + cv2.rectangle(color, (x - 2, y - 2), (x + w + 2, y + h + 2), (0, 0, 255), 1) | ||
54 | + digit_arr.append(bin_tmp[y - 2:y + h + 2, x - 2:x + w + 2]) | ||
55 | + if count == 10: | ||
56 | + digit_arr2.append(digit_arr) | ||
57 | + digit_arr = [] | ||
58 | + count = 0 | ||
59 | + cv2.imshow('contours', color) | ||
60 | + | ||
61 | + k = cv2.waitKey(0) | ||
62 | + cv2.destroyAllWindows() | ||
63 | + | ||
64 | + for i in range(0, len(digit_arr2)): | ||
65 | + for j in range(len(digit_arr2[i])): | ||
66 | + count += 1 | ||
67 | + if i == 0: # 1일 경우 비율 유지를 위해 마스크를 만들어 그위에 얹어줌 | ||
68 | + width = digit_arr2[i][j].shape[1] | ||
69 | + height = digit_arr2[i][j].shape[0] | ||
70 | + tmp = (height - width) / 2 | ||
71 | + mask = np.zeros((height, height)) | ||
72 | + mask[0:height, int(tmp):int(tmp) + width] = digit_arr2[i][j] | ||
73 | + digit_arr2[i][j] = cv2.resize(mask, (28, 28)) | ||
74 | + else: | ||
75 | + digit_arr2[i][j] = cv2.resize(digit_arr2[i][j], (28, 28)) | ||
76 | + # if i == 9 : i = -1 | ||
77 | + cv2.imwrite(f"./juno/data/{i}/" + str(i) + '_' + str(j) + f"_{filename.split('.')[0]}.png", digit_arr2[i][j]) | ||
78 | + | ||
79 | +for filename in filenames: | ||
80 | + generate_dataset(filename) | ||
81 | + | ||
82 | +# def createdataset(directory): #sklearn사용을 위해 데이터세트를 생성 | ||
83 | +# files = os.listdir(directory) | ||
84 | +# x = [] | ||
85 | +# y = [] | ||
86 | +# for file in files: | ||
87 | +# attr_x = cv2.imread(directory+file, cv2.IMREAD_GRAYSCALE) | ||
88 | +# attr_x = attr_x.flatten() | ||
89 | +# attr_y = file[0] | ||
90 | +# x.append(attr_x) | ||
91 | +# y.append(attr_y) | ||
92 | +# | ||
93 | +# x = np.array(x) | ||
94 | +# y = np.array(y) | ||
95 | +# return x , y | ||
96 | +# | ||
97 | +# train_dir = './juno/data/' | ||
98 | +# train_x ,train_y = createdataset(train_dir) | ||
99 | +# test_dir = './juno/test/' | ||
100 | +# test_x , test_y = createdataset(test_dir) |
-
Please register or login to post a comment