├── .gitignore ├── LICENSE ├── README.md ├── download_cl1024_images.py ├── imagesmake.py └── playGTA5 ├── modules.py └── play.py /.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 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 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 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 kurtlab 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python project 2 | 3 | Python 语言学习的收集的项目的代码 4 | 5 | imagesmake - 按照给的关键词在百度图片下载图片然后生成千图图片 6 | download_cl1024_images - 下载某社区的图片 7 | 8 | 用到的模块 9 | 10 | requests 11 | pillow 12 | pyinstaller 13 | tkinter 14 | 15 | ###2019年10月11日 16 | 17 | 添加使用python玩gta5的代码;不断改善 18 | 19 | -------------------------------------------------------------------------------- /download_cl1024_images.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import tkinter as tk 5 | from tkinter import messagebox 6 | from tkinter.filedialog import askdirectory, askopenfilename 7 | import threading, time, re, os, requests, math 8 | from PIL import Image, ImageStat 9 | 10 | def thread_run(func): 11 | def wraper(*args, **kwargs): 12 | t = threading.Thread(target=func, args=args, kwargs=kwargs) 13 | t.daemon = True 14 | t.start() 15 | 16 | return wraper 17 | 18 | 19 | class ImageManager(): 20 | def __init__(self, file=None, io=None, im=None): 21 | self.mean = None 22 | self.im = None 23 | self.path = None 24 | 25 | if file: 26 | if not os.path.exists(file): 27 | raise Exception("文件不存在的!") 28 | 29 | self.path = file 30 | self.im = Image.open(file) 31 | if im: 32 | self.im = im 33 | 34 | def getMean(self): 35 | if not self.mean: 36 | self.mean = ImageStat.Stat(self.im.convert('L')).mean[0] 37 | 38 | return self.mean 39 | 40 | def resize(self, size=(1, 1)): 41 | return self.im.resize(size, Image.ANTIALIAS) 42 | # return self.im.resize(size) 43 | 44 | 45 | class BasicFrame(object): 46 | """Frame基类,实现grid方法""" 47 | 48 | def __init__(self, root=None, **args): 49 | super(BasicFrame, self).__init__() 50 | self.root = None 51 | if root: 52 | self.root = tk.Frame(root) 53 | if args and 'root' in args.keys: 54 | self.root = tk.Frame(args.root) 55 | 56 | if not self.root: 57 | raise Exception("no root") 58 | 59 | def grid(self, row='default', column='default', **args): 60 | if row == 'default' or column == 'default': 61 | if args: 62 | self.root.grid(**args) 63 | else: 64 | self.root.grid(row=row, column=column) 65 | 66 | 67 | class DownloadFrame(BasicFrame): 68 | """docstring for SearchFrame""" 69 | 70 | def __init__(self, root=None, **args): 71 | super(DownloadFrame, self).__init__(root=root, **args) 72 | self.entry = tk.StringVar() 73 | self.cnt = 0 74 | self.num = tk.StringVar() 75 | self.num.set(300) 76 | self.name = 0 77 | self.flag = False 78 | 79 | row = 0 80 | 81 | tk.Label(self.root, text='----请输入要下载的免翻地址---').grid(row=row, column=1) 82 | 83 | row += 1 84 | tk.Label(self.root,width=10, justify='right' ,text='地址').grid(row=row, column=0) 85 | tk.Entry(self.root, textvariable=self.entry, width=24).grid(row=row, column=1) 86 | tk.Button(self.root, width=9,text='下载图片', command=self.downloadnow).grid(row=row, column=2) 87 | 88 | 89 | row += 1 90 | 91 | tk.Label(self.root, text='---代理功能更新中---').grid(row=row, column=1) 92 | 93 | 94 | 95 | @thread_run 96 | def downloadnow(self): 97 | _input = self.entry.get().replace(' ', '') 98 | 99 | if self.flag: 100 | messagebox.showinfo("警告", "尚有后台下载任务进行中") 101 | elif _input == '' : 102 | messagebox.showinfo("警告", "链接不能为空") 103 | else: 104 | self.entry.set('') 105 | self.prepare(_input) 106 | 107 | def prepare(self, downloadlinks): 108 | self.flag = True 109 | self.downloadlinks = downloadlinks 110 | self.base_url = self.downloadlinks 111 | 112 | fail = 0 113 | 114 | try: 115 | url = self.base_url 116 | result = requests.get(url, timeout=10) 117 | result.encoding = 'gbk' 118 | # pic_url = re.findall('"objURL":"(.*?)",', result.text, re.S) 119 | pic_url = re.findall("data-src='(.*?)'", result.text, re.S) 120 | 121 | if pic_url: 122 | pic_url 123 | print(pic_url) 124 | else: 125 | pic_url = re.findall("ess-data='(.*?)'", result.text, re.S) 126 | print(pic_url) 127 | titles = re.findall('

(.+)

', result.text) 128 | print(titles) 129 | title = titles[0] 130 | print(title) 131 | path = "%s\\%s" % (os.path.abspath('.'), title) 132 | if not os.path.exists(path): 133 | os.mkdir(path) 134 | 135 | if len(pic_url) == 0: 136 | fail += 1 137 | else: 138 | self.downloadPic(pic_url, path) 139 | except Exception as e: 140 | print(e) 141 | time.sleep(3) 142 | 143 | 144 | # print("图片下载完成") 145 | 146 | def downloadPic(self, urls, path): 147 | 148 | # 每过三秒检查一次当前正在运行的线程数,超标则沉睡等待线程结束 149 | while threading.activeCount() > 5: 150 | print("线程超标---%s" % threading.activeCount()) 151 | time.sleep(3) 152 | 153 | for url in urls: 154 | if url: 155 | print(url) 156 | self.download(url, path) 157 | 158 | 159 | @thread_run 160 | def download(self, url, path): 161 | try: 162 | if lock.acquire(): 163 | self.name += 1 164 | filename = "%s\\%s.%s" % (path, self.name, url.split('.')[-1]) 165 | lock.release() 166 | header = { 167 | "accept-ranges":"bytes", 168 | "age":"8585", 169 | "cache-control":"public, max-age=31536000", 170 | "cf-cache-status":"HIT", 171 | "content-length":"729911", 172 | "content-type":"image/jpeg", 173 | "server":"cloudflare", 174 | "status":"200", 175 | "vary":"Accept-Encoding"} 176 | print('start down load images') 177 | print(url) 178 | print(filename) 179 | # res = requests.get(url, headers=header ) 180 | res = requests.get(url ) 181 | with open(filename, 'wb') as f: 182 | f.write(res.content) 183 | # 下载完后检查是否完成下载 184 | if lock.acquire(): 185 | if self.flag: 186 | self.flag = False 187 | messagebox.showinfo("提示", "下载完成") 188 | 189 | except Exception as e: 190 | print(e) 191 | if lock.acquire(): 192 | self.cnt -= 1 193 | lock.release() 194 | 195 | 196 | 197 | if __name__ == '__main__': 198 | lock = threading.Lock() 199 | root = tk.Tk() 200 | root.title("社区图片下载器[社区定制] -- 正则兮") 201 | root.geometry('440x150+600+200') 202 | root.resizable(False, False) 203 | 204 | downloadnow = DownloadFrame(root) 205 | downloadnow.grid(0, 0) 206 | 207 | 208 | tk.Label(text="created BY 正则兮").grid(row=2, column=0) 209 | 210 | root.mainloop() -------------------------------------------------------------------------------- /imagesmake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import tkinter as tk 5 | from tkinter import messagebox 6 | from tkinter.filedialog import askdirectory, askopenfilename 7 | import threading, time, re, os, requests, math 8 | from PIL import Image, ImageStat 9 | 10 | def thread_run(func): 11 | def wraper(*args, **kwargs): 12 | t = threading.Thread(target=func, args=args, kwargs=kwargs) 13 | t.daemon = True 14 | t.start() 15 | 16 | return wraper 17 | 18 | 19 | class ImageManager(): 20 | def __init__(self, file=None, io=None, im=None): 21 | self.mean = None 22 | self.im = None 23 | self.path = None 24 | 25 | if file: 26 | if not os.path.exists(file): 27 | raise Exception("文件不存在的!") 28 | 29 | self.path = file 30 | self.im = Image.open(file) 31 | if im: 32 | self.im = im 33 | 34 | def getMean(self): 35 | if not self.mean: 36 | self.mean = ImageStat.Stat(self.im.convert('L')).mean[0] 37 | 38 | return self.mean 39 | 40 | def resize(self, size=(1, 1)): 41 | return self.im.resize(size, Image.ANTIALIAS) 42 | # return self.im.resize(size) 43 | 44 | 45 | class BasicFrame(object): 46 | """Frame基类,实现grid方法""" 47 | 48 | def __init__(self, root=None, **args): 49 | super(BasicFrame, self).__init__() 50 | self.root = None 51 | if root: 52 | self.root = tk.Frame(root) 53 | if args and 'root' in args.keys: 54 | self.root = tk.Frame(args.root) 55 | 56 | if not self.root: 57 | raise Exception("no root") 58 | 59 | def grid(self, row='default', column='default', **args): 60 | if row == 'default' or column == 'default': 61 | if args: 62 | self.root.grid(**args) 63 | else: 64 | self.root.grid(row=row, column=column) 65 | 66 | 67 | class SearchFrame(BasicFrame): 68 | """docstring for SearchFrame""" 69 | 70 | def __init__(self, root=None, **args): 71 | super(SearchFrame, self).__init__(root=root, **args) 72 | self.entry = tk.StringVar() 73 | self.cnt = 0 74 | self.num = tk.StringVar() 75 | self.num.set(300) 76 | self.name = 0 77 | self.flag = False 78 | 79 | row = 0 80 | 81 | tk.Label(self.root, text='----搜索下载图片区域---').grid(row=row, column=1) 82 | 83 | row += 1 84 | tk.Label(self.root,width=10, justify='right' ,text='关键词').grid(row=row, column=0) 85 | tk.Entry(self.root, textvariable=self.entry, width=24).grid(row=row, column=1) 86 | tk.Button(self.root, width=9,text='下载图片', command=self.serach).grid(row=row, column=2) 87 | tk.Label(self.root, width=30, justify='right' , text='直接输入关键词,调用百度图片').grid(row=row, column=3) 88 | 89 | row += 1 90 | tk.Label(self.root, width=9, justify='right' , text='爬取量').grid(row=row, column=0) 91 | self.button = tk.Entry(self.root, textvariable=self.num, width=24).grid(row=row, column=1) 92 | 93 | row += 1 94 | 95 | tk.Label(self.root, text='---生成图片设置区域---').grid(row=row, column=1) 96 | 97 | 98 | 99 | @thread_run 100 | def serach(self): 101 | _input = self.entry.get().replace(' ', '') 102 | try: 103 | num = int(self.num.get()) 104 | except Exception as e: 105 | num = 0 106 | print(e) 107 | 108 | if self.flag: 109 | messagebox.showinfo("警告", "尚有后台下载任务进行中") 110 | elif _input == '' or num == 0: 111 | messagebox.showinfo("警告", "关键词或爬取量不能为空") 112 | else: 113 | self.entry.set('') 114 | self.prepare(_input) 115 | 116 | def prepare(self, keywords): 117 | self.flag = True 118 | self.keywords = keywords 119 | self.base_url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + self.keywords + '&pn=' 120 | 121 | path = "%s\\%s" % (os.path.abspath('.'), keywords) 122 | if not os.path.exists(path): 123 | os.mkdir(path) 124 | 125 | t = 0 126 | self.cnt = 0 127 | fail = 0 128 | while True: 129 | if fail > 10: 130 | if self.flag: 131 | self.flag = False 132 | messagebox.showinfo("提示", "下载完成,但该词条下无足够数量图片!!!") 133 | return 134 | 135 | if (self.cnt >= int(self.num.get())): 136 | if self.flag: 137 | self.flag = False 138 | messagebox.showinfo("提示", "下载完成") 139 | return 140 | try: 141 | url = self.base_url + str(t) 142 | result = requests.get(url, timeout=10) 143 | pic_url = re.findall('"objURL":"(.*?)",', result.text, re.S) 144 | if len(pic_url) == 0: 145 | fail += 1 146 | else: 147 | self.downloadPic(pic_url, path) 148 | except Exception as e: 149 | print(e) 150 | time.sleep(3) 151 | finally: 152 | t += 60 153 | time.sleep(1) 154 | 155 | # print("图片下载完成") 156 | 157 | def downloadPic(self, urls, path): 158 | 159 | # 每过三秒检查一次当前正在运行的线程数,超标则沉睡等待线程结束 160 | while threading.activeCount() > 200: 161 | print("线程超标---%s" % threading.activeCount()) 162 | time.sleep(3) 163 | 164 | for url in urls: 165 | if url: 166 | self.download(url, path) 167 | 168 | @thread_run 169 | def download(self, url, path): 170 | try: 171 | if lock.acquire(): 172 | if (self.cnt >= int(self.num.get())): 173 | lock.release() 174 | return 175 | self.cnt += 1 176 | self.name += 1 177 | filename = "%s\\%s_%s.%s" % (path, self.keywords, self.name, url.split('.')[-1]) 178 | lock.release() 179 | 180 | res = requests.get(url, timeout=10) 181 | with open(filename, 'wb') as f: 182 | f.write(res.content) 183 | # 下载完后检查是否完成下载 184 | if lock.acquire(): 185 | if (self.cnt >= int(self.num.get())): 186 | lock.release() 187 | if self.flag: 188 | self.flag = False 189 | messagebox.showinfo("提示", "下载完成") 190 | else: 191 | lock.release() 192 | except Exception as e: 193 | print(e) 194 | if lock.acquire(): 195 | self.cnt -= 1 196 | lock.release() 197 | 198 | 199 | class GenerateFrame(BasicFrame): 200 | """docstring for GenerateFrame""" 201 | 202 | def __init__(self, root=None, **args): 203 | super(GenerateFrame, self).__init__(root=root, **args) 204 | self.path = tk.StringVar() # 用于保存输入源目录 205 | # self.path = path # 用于保存输入源目录 206 | self.output = tk.StringVar() # 用于保存输出对象路径 207 | self.resources = [] 208 | self.orign = None 209 | self.outim = None 210 | self.busy = False 211 | self.load = False 212 | 213 | self.width = tk.StringVar() 214 | self.row = tk.StringVar() 215 | self.column = tk.StringVar() 216 | self.images = [] 217 | 218 | self.row.set('60') 219 | self.column.set('60') 220 | self.width.set('30') 221 | 222 | row = 0 223 | tk.Label(self.root,width=10, justify='right' , text='输入源路径').grid(row=row, column=0) 224 | tk.Entry(self.root, textvariable=self.path, width=24).grid(row=row, column=1) 225 | tk.Button(self.root, text='载入输入源', command=self.setResource).grid(row=row, column=2) 226 | tk.Label(self.root, width=30, justify='right' , text='选择图片来源文件夹').grid(row=row, column=3) 227 | 228 | 229 | row += 1 230 | tk.Label(self.root, width=10, justify='right' ,text='输出源路径').grid(row=row, column=0) 231 | tk.Entry(self.root, textvariable=self.output, width=24).grid(row=row, column=1) 232 | tk.Button(self.root, text='选择输出源', command=self.setOrign).grid(row=row, column=2) 233 | tk.Label(self.root, text='选择要生成的图片源').grid(row=row, column=3) 234 | 235 | row += 1 236 | tk.Label(self.root, width=10, justify='right' ,text='图片宽度').grid(row=row, column=0) 237 | tk.Entry(self.root, textvariable=self.width, width=24).grid(row=row, column=1) 238 | tk.Button(self.root, text='生成图片', command=self.generate).grid(row=row, column=2) 239 | tk.Label(self.root, text='填充的图片的宽度').grid(row=row, column=3) 240 | row += 1 241 | tk.Label(self.root, width=10, justify='right' ,text='图片行数').grid(row=row, column=0) 242 | tk.Entry(self.root, textvariable=self.row, width=24).grid(row=row, column=1) 243 | # tk.Button(self.root, text = '保存图片', command = self.saveImg).grid(row=row, column=2) 244 | 245 | row += 1 246 | tk.Label(self.root, width=10, justify='right' ,text='图片列数').grid(row=row, column=0) 247 | tk.Entry(self.root, textvariable=self.column, width=24).grid(row=row, column=1) 248 | 249 | @thread_run 250 | def setResource(self, ): 251 | try: 252 | self.load = True 253 | self.resources = [] 254 | self.path.set(askdirectory(title="载入输入源")) 255 | self.images = self.getImages(self.path.get()) 256 | for img in self.images: 257 | self.resources.append(ImageManager(img)) 258 | except Exception as e: 259 | pass 260 | finally: 261 | self.load = False 262 | 263 | @thread_run 264 | def setOrign(self): 265 | orign = askopenfilename(title='选择输出源', filetypes=[('jpg', '*.jpg'), ('jpeg', '*.jpeg'), ('png', '*.png')]) 266 | 267 | self.output.set(orign) 268 | 269 | self.orign = ImageManager(orign) 270 | 271 | @thread_run 272 | def generate(self, ): 273 | if self.load: 274 | messagebox.showinfo("警告", "图片源加载尚未完成,请等待...") 275 | return 276 | if self.busy: 277 | messagebox.showinfo("警告", "上一个合成任务仍在进行中...") 278 | return 279 | try: 280 | self.busy = True 281 | width = int(self.column.get()) 282 | height = int(self.row.get()) 283 | length = int(self.width.get()) 284 | 285 | self.outim = self.orign.resize((width * length, height * length)) 286 | for i in range(height): 287 | for j in range(width): 288 | manager = ImageManager( 289 | im=self.outim.crop((i * length, j * length, (i + 1) * length, (j + 1) * length))) 290 | rgion = self.getMin(manager, self.resources) 291 | box = (i * length, j * length, (i + 1) * length, (j + 1) * length) 292 | self.outim.paste(rgion.resize((length, length)), box) 293 | 294 | self.saveImg() 295 | messagebox.showinfo("提示", "生成图片成功!!!") 296 | 297 | except Exception as e: 298 | messagebox.showinfo("提示", "生成图片失败,请重试...") 299 | print(e) 300 | finally: 301 | self.busy = False 302 | 303 | def saveImg(self, ): 304 | if self.outim: 305 | self.outim.save('%s.png' % int(time.time()), quality=95) 306 | 307 | def getImages(self, path): 308 | tmp = [] 309 | for root, dirs, files in os.walk(path): 310 | if files and len(files) > 0: 311 | for file in files: 312 | if 'jpg' in file or 'jpeg' in file or 'png' in file: 313 | tmp.append(root + '/' + file) 314 | if dirs and len(dirs) > 0: 315 | for _dir in dirs: 316 | tmp += self.getImages(root + '/' + _dir) 317 | 318 | return tmp 319 | 320 | def getMin(self, point, points): 321 | _min = points[0] 322 | _mean = point.getMean() 323 | _dis = math.fabs(_min.getMean() - _mean) 324 | for p in points: 325 | if math.fabs(p.getMean() - _mean) < _dis: 326 | _min = p 327 | _dis = math.fabs(p.getMean() - _mean) 328 | 329 | return _min 330 | 331 | 332 | if __name__ == '__main__': 333 | lock = threading.Lock() 334 | root = tk.Tk() 335 | root.title("图片生成器 -- 正则兮") 336 | root.geometry('640x280+600+200') 337 | root.resizable(False, False) 338 | 339 | serach = SearchFrame(root) 340 | serach.grid(0, 0) 341 | 342 | generate = GenerateFrame(root) 343 | generate.grid(1, 0) 344 | 345 | tk.Label(text="created BY 正则兮").grid(row=2, column=0) 346 | 347 | root.mainloop() -------------------------------------------------------------------------------- /playGTA5/modules.py: -------------------------------------------------------------------------------- 1 | # -*- urf-8 -*- 2 | import numpy as np 3 | from numpy import one,vstack 4 | from numpy.linalg import lstsq 5 | from statistics import mean 6 | from PIL import ImageGreb 7 | import cv2 8 | import time 9 | 10 | def captur(x=0 ,y=0,width=13, height=14): 11 | return np.array(ImageGreb.grar(bbox=(x, y, width, height))) 12 | 13 | def roi (img, vertices): 14 | mask = np.zeros_like(img) 15 | cv2.fillPoly(mask, [vertices],255) 16 | masked = cv2.bitwise_and(img, mask) 17 | return masked 18 | 19 | def show(image): 20 | cv2.imshow("Window", image) 21 | if cv2.waitKey(25) & 0xFF == ord("q"): 22 | cv2.destroyAllWindows() 23 | return False 24 | return True 25 | 26 | def theta_of(line): 27 | return (line[2] - line[0]) / np.linalg.norm(line) 28 | 29 | def proces(image): 30 | # color fix 31 | processed_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 32 | 33 | # edge deltection -------------------------------------------------------------------------------- /playGTA5/play.py: -------------------------------------------------------------------------------- 1 | # -*- utf-8 -*- --------------------------------------------------------------------------------