├── SmokeRelated ├── SmokeVideos │ └── vid11.mp4 ├── SmokeStaticImages │ └── nonfire.6226.jpg └── SmokeDataSet │ └── Edited_vid11.mp4_nonfire.6226.jpg_resizeRatio_3_region_2_rotationDegree_0_false.avi ├── README.md ├── LICENSE ├── .gitignore ├── mergeimages.py └── MergingClass.py /SmokeRelated/SmokeVideos/vid11.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogusyuksel/CreatingSyntheticSmokeVideos/HEAD/SmokeRelated/SmokeVideos/vid11.mp4 -------------------------------------------------------------------------------- /SmokeRelated/SmokeStaticImages/nonfire.6226.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogusyuksel/CreatingSyntheticSmokeVideos/HEAD/SmokeRelated/SmokeStaticImages/nonfire.6226.jpg -------------------------------------------------------------------------------- /SmokeRelated/SmokeDataSet/Edited_vid11.mp4_nonfire.6226.jpg_resizeRatio_3_region_2_rotationDegree_0_false.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogusyuksel/CreatingSyntheticSmokeVideos/HEAD/SmokeRelated/SmokeDataSet/Edited_vid11.mp4_nonfire.6226.jpg_resizeRatio_3_region_2_rotationDegree_0_false.avi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CreatingSyntheticSmokeVideo 2 | For early fire detection, smoke must be detect first. This project create smoke videos to feed deep laerning dataset 3 | With this project, we can create new videos from one smoke video by combining it with different bakround images. 4 | 5 | Also with this project, there are several options like; 6 | - Resizing smoke part in 4 different ways 7 | - Selecting location to put smoke in static image in 4 different ways 8 | - Rotation smoke part in 5 different angle 9 | 10 | So, with one smoke video and static image, 80 different smoke videos can be created. 11 | 12 | 13 | To run the project, do the follows; 14 | 15 | 1. Put your backround images in the path "SmokeRelated/SmokeStaticImages" 16 | 2. Put your smoked video in the path "SmokeRelated/SmokeVideos" 17 | BE CAREFULL, SMOKE VIDEOS MUST HAVE GREEN STATIC BACKROUND, these kinds of videos can be found in youtube 18 | 3. Run the "mergingimages.py" 19 | 4. Observe output videos in the path "SmokeRelated/SmokeDataSet" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 dogusyuksel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /mergeimages.py: -------------------------------------------------------------------------------- 1 | from MergingClass import MergingClass 2 | import os 3 | 4 | # REGIONS 5 | #--------------------- 6 | #| 1 | 2 | 7 | #-------------------- 8 | #| 3 | 4 | 9 | #------------------- 10 | 11 | 12 | # Do not touch this part 13 | DEFINE_REGION_1 = 1 14 | DEFINE_REGION_2 = 2 15 | DEFINE_REGION_3 = 3 16 | DEFINE_REGION_4 = 4 17 | 18 | DEFINE_NO_ROTATION = 0 19 | DEFINE_ROTATION_RIGHTUP = 1 20 | DEFONE_ROTATION_LEFTUP = 2 21 | DEFINE_ROTATION_LEFT = 3 22 | DEFINE_ROTATION_RIGHT = 4 23 | 24 | DEFINE_X_PIXEL_MULTIPLICATION = 40 25 | DEFINE_Y_PIXEL_MULTIPLICATION = 30 26 | 27 | DEFINE_BACKROUND_IMAGE_FOLDER = "SmokeRelated/SmokeStaticImages/" 28 | DEFIE_SMOKE_VIDEO_FOLDER = "SmokeRelated/SmokeVideos/" 29 | DEFINE_OUTPUT_VIDEO_FOLDER = "SmokeRelated/SmokeDataSet/" 30 | # End of do not touch 31 | 32 | DEFINE_RESIZED_VIDEO_X_LEN = 320 33 | DEFINE_RESIZED_VIDEO_Y_LEN = 240 34 | DEFINE_SMOKE_VIDE_RESIZE_RATIO_WRT_RESIZED_VIDEO = 4 #between 1 to 4 35 | DEFINE_SMOKE_VIDEO_MERGE_REGION_SELECTION = DEFINE_REGION_2 36 | DEFINE_ROTATION_DEGREE = DEFINE_NO_ROTATION 37 | DEFINE_OUTPUT_VIDEO_FPS = 25.0 38 | 39 | DEFINE_SMOKE_VIDEO_FILENAME = "vid15.avi" 40 | DEFINE_STATIC_IMAGE_FILENAME = "nonfire.390.jpg" 41 | DEFINE_OUTPUT_VIDEO_FILENAME = "Edited_" + str(DEFINE_STATIC_IMAGE_FILENAME) + "_resizeRatio_" + str(DEFINE_SMOKE_VIDE_RESIZE_RATIO_WRT_RESIZED_VIDEO) + "_region_" + str(DEFINE_SMOKE_VIDEO_MERGE_REGION_SELECTION) + "_rotationDegree_" + str(DEFINE_ROTATION_DEGREE) + ".avi" 42 | 43 | DEFINE_IS_OUTPUT_GREYSCALE = 'false' 44 | 45 | 46 | def findfiles(directory): 47 | objects = os.listdir(directory) # find all objects in a dir 48 | 49 | files = [] 50 | for i in objects: # check if very object in the folder ... 51 | if isFile(directory + i): # ... is a file. 52 | files.append(i) # if yes, append it. 53 | return files 54 | 55 | def isFile(object): 56 | try: 57 | os.listdir(object) # tries to get the objects inside of this object 58 | return False # if it worked, it's a folder 59 | except Exception: # if not, it's a file 60 | return True 61 | 62 | 63 | 64 | # get all video names here 65 | the_list_video = findfiles("SmokeRelated/SmokeVideos") 66 | 67 | # get all static images here 68 | the_list_image = findfiles("SmokeRelated/SmokeStaticImages") 69 | 70 | 71 | img_rotat = 0 72 | img_res = 0 73 | img_reg = 0 74 | grey_cnt = 0 75 | video_cnt = 0 76 | 77 | for i in the_list_video: 78 | for j in the_list_image: 79 | DEFINE_SMOKE_VIDEO_FILENAME = str(i) 80 | DEFINE_STATIC_IMAGE_FILENAME = str(j) 81 | for img_rotat in range(0, 5): 82 | DEFINE_ROTATION_DEGREE = img_rotat 83 | for img_res in range(1, 5): 84 | DEFINE_SMOKE_VIDE_RESIZE_RATIO_WRT_RESIZED_VIDEO = img_res 85 | for img_reg in range(1, 5): 86 | DEFINE_SMOKE_VIDEO_MERGE_REGION_SELECTION = img_reg 87 | DEFINE_IS_OUTPUT_GREYSCALE = 'false' 88 | 89 | # stars main code here 90 | video_cnt = video_cnt + 1 91 | DEFINE_OUTPUT_VIDEO_FILENAME = "Edited_" + str(DEFINE_SMOKE_VIDEO_FILENAME) + "_" + str(DEFINE_STATIC_IMAGE_FILENAME) + "_resizeRatio_" + str(DEFINE_SMOKE_VIDE_RESIZE_RATIO_WRT_RESIZED_VIDEO) + "_region_" + str(DEFINE_SMOKE_VIDEO_MERGE_REGION_SELECTION) + "_rotationDegree_" + str(DEFINE_ROTATION_DEGREE) + "_" + str(DEFINE_IS_OUTPUT_GREYSCALE) + ".avi" 92 | mergeInstance = MergingClass(DEFINE_RESIZED_VIDEO_X_LEN, DEFINE_RESIZED_VIDEO_Y_LEN, DEFINE_SMOKE_VIDE_RESIZE_RATIO_WRT_RESIZED_VIDEO, DEFINE_SMOKE_VIDEO_MERGE_REGION_SELECTION, DEFINE_ROTATION_DEGREE, DEFINE_OUTPUT_VIDEO_FPS, DEFINE_IS_OUTPUT_GREYSCALE) 93 | mergeInstance.merge(DEFINE_BACKROUND_IMAGE_FOLDER + DEFINE_STATIC_IMAGE_FILENAME, DEFIE_SMOKE_VIDEO_FOLDER + DEFINE_SMOKE_VIDEO_FILENAME, DEFINE_OUTPUT_VIDEO_FOLDER+DEFINE_OUTPUT_VIDEO_FILENAME) 94 | print("Finished " + str(video_cnt) + ". video!") 95 | 96 | 97 | print("End of This Process!") 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /MergingClass.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | class MergingClass(): 5 | def __init__(self, out_vid_x_len = 320, out_vid_y_len = 240, second_vid_resized_ratio = 4, merging_region = 1, second_vid_rotation = 0, out_vid_fps = 25, is_grey_out = 'false'): 6 | """Either load pretrained from imagenet, or load our saved 7 | weights from our own training.""" 8 | 9 | self.out_vid_x_len = out_vid_x_len 10 | self.out_vid_y_len = out_vid_y_len 11 | self.second_vid_resized_ratio = second_vid_resized_ratio 12 | self.merging_region = merging_region 13 | self.second_vid_rotation = second_vid_rotation 14 | self.out_vid_fps = out_vid_fps 15 | self.is_grey_out = is_grey_out 16 | 17 | def merge(self, inp_image_path, inp_video_path, out_vid_path): 18 | 19 | ###################CONFIG 20 | DEFINE_X_PIXEL_MULTIPLICATION = 40 21 | DEFINE_Y_PIXEL_MULTIPLICATION = 30 22 | 23 | DEFINE_REGION_1 = 1 24 | DEFINE_REGION_2 = 2 25 | DEFINE_REGION_3 = 3 26 | DEFINE_REGION_4 = 4 27 | 28 | DEFINE_NO_ROTATION = 0 29 | DEFINE_ROTATION_LEFT = 1 30 | DEFONE_ROTATION_LEFTUP = 2 31 | DEFINE_ROTATION_RIGHTUP = 3 32 | DEFINE_ROTATION_RIGHT = 4 33 | ##############END CONFIG 34 | 35 | cap = cv2.VideoCapture(inp_video_path) 36 | 37 | # Define the codec and create VideoWriter object 38 | fourcc = cv2.VideoWriter_fourcc(*'XVID') 39 | out = cv2.VideoWriter(out_vid_path, fourcc, self.out_vid_fps , (self.out_vid_x_len, self.out_vid_y_len)) 40 | 41 | otherImage = cv2.imread(inp_image_path, cv2.IMREAD_COLOR) 42 | otherImage = cv2.resize(otherImage,(self.out_vid_x_len, self.out_vid_y_len)) 43 | clone_img = otherImage.copy() 44 | 45 | lenMultiplier = 4 46 | if(self.second_vid_resized_ratio == 1): 47 | lenMultiplier = 1 48 | elif(self.second_vid_resized_ratio == 2): 49 | lenMultiplier = 2 50 | elif(self.second_vid_resized_ratio == 3): 51 | lenMultiplier = 3 52 | elif(self.second_vid_resized_ratio == 4): 53 | lenMultiplier = 4 54 | 55 | smoke_vide_resized_x_len = DEFINE_X_PIXEL_MULTIPLICATION * lenMultiplier 56 | smoke_vide_resized_y_len = DEFINE_Y_PIXEL_MULTIPLICATION * lenMultiplier 57 | 58 | 59 | myImageWithTransparency = np.zeros([smoke_vide_resized_y_len,smoke_vide_resized_x_len,3],dtype=np.uint8) 60 | myImageWithTransparency.fill(0) # or img[:] = 255 61 | 62 | x_shift = 0 63 | y_shift = 0 64 | 65 | if(self.merging_region == DEFINE_REGION_1): 66 | #1. region 67 | y_shift = 0 68 | x_shift = 0 69 | elif(self.merging_region == DEFINE_REGION_2): 70 | #2. region 71 | y_shift = self.out_vid_x_len - smoke_vide_resized_x_len - 1 72 | x_shift = 0 73 | elif(self.merging_region == DEFINE_REGION_3): 74 | #3. region 75 | y_shift = 0 76 | x_shift = self.out_vid_y_len - smoke_vide_resized_y_len - 1 77 | elif(self.merging_region == DEFINE_REGION_4): 78 | #4. region 79 | y_shift = self.out_vid_x_len - smoke_vide_resized_x_len - 1 80 | x_shift = self.out_vid_y_len - smoke_vide_resized_y_len - 1 81 | 82 | 83 | rotation_contant = DEFINE_NO_ROTATION 84 | if(self.second_vid_rotation == DEFINE_NO_ROTATION): 85 | rotation_contant = 0 86 | elif(self.second_vid_rotation == DEFINE_ROTATION_LEFT): 87 | rotation_contant = 90 88 | elif(self.second_vid_rotation == DEFINE_ROTATION_RIGHTUP): 89 | rotation_contant = -45 90 | elif(self.second_vid_rotation == DEFONE_ROTATION_LEFTUP): 91 | rotation_contant = 45 92 | elif(self.second_vid_rotation == DEFINE_ROTATION_RIGHT): 93 | rotation_contant = -90 94 | 95 | 96 | 97 | mask = np.zeros([smoke_vide_resized_y_len,smoke_vide_resized_x_len,3],dtype=np.uint8) 98 | mask.fill(0) # or img[:] = 255 99 | 100 | 101 | while(cap.isOpened()): 102 | ret, frame = cap.read() 103 | if ret==True: 104 | #sleep(0.5) 105 | 106 | frame = cv2.resize(frame,(smoke_vide_resized_x_len, smoke_vide_resized_y_len)) 107 | 108 | 109 | M = cv2.getRotationMatrix2D((smoke_vide_resized_x_len/2, smoke_vide_resized_y_len/2), rotation_contant, 1) 110 | frame = cv2.warpAffine(frame, M, (smoke_vide_resized_x_len, smoke_vide_resized_y_len)) 111 | 112 | otherImage = clone_img.copy() 113 | # manipulate background 114 | for y in range(0, smoke_vide_resized_x_len): 115 | for x in range(0, smoke_vide_resized_y_len): 116 | threeColor = frame[x, y] 117 | threeColor2 = otherImage[x + x_shift, y + y_shift] 118 | if ((threeColor[0] < 127) and (threeColor[1] > 127) and (threeColor[2] < 127)): #it is green 119 | threeColor2 = otherImage[x + x_shift, y + y_shift] 120 | else: 121 | threeColor2 = frame[x, y] 122 | 123 | if ((threeColor[0] == 0) and (threeColor[1] == 0) and (threeColor[2] == 0)): #it is green 124 | threeColor2 = otherImage[x + x_shift, y + y_shift] 125 | 126 | otherImage[x + x_shift, y + y_shift] = threeColor2 127 | 128 | 129 | if(self.is_grey_out == 'true'): 130 | otherImage = cv2.cvtColor(otherImage, cv2.COLOR_BGR2GRAY); 131 | 132 | 133 | # write the flipped frame 134 | out.write(otherImage) 135 | 136 | cv2.imshow('frame',otherImage) 137 | if cv2.waitKey(1) & 0xFF == ord('q'): 138 | break 139 | else: 140 | break 141 | 142 | # Release everything if job is finished 143 | cap.release() 144 | out.release() 145 | cv2.destroyAllWindows() --------------------------------------------------------------------------------