Làm cách nào để bạn tạo hình ảnh ngẫu nhiên trong python?

Một API sẽ cho phép giao tiếp giữa hai ứng dụng. API tôi đang sử dụng là API dựa trên web có sẵn công khai, trả về dữ liệu dưới dạng JSON hoặc XML. Nói cách khác, tôi gửi tin nhắn đến một trang web đã nêu và yêu cầu một số dữ liệu, trong trường hợp này, hình ảnh sau đó được trả lại cho tôi.


Sử dụng python 2 có một chút khác biệt trong mã hóa.



Điều đáng chú ý là ['file'] ở cuối json. loading[] có thể khác với trang web bạn đang kết nối. Tôi đã kết nối với Randomcat. com.

Bài đăng này được lấy cảm hứng từ các bộ sưu tập nghệ thuật NFT đã được phát hành gần đây, chẳng hạn như Cryptopunks, Sollamas, ON1 Force hoặc Bored Ape Yacht Club. Trong số tất cả các dự án này, có một số dự án trong đó hình ảnh được tạo bởi các nghệ sĩ trong khi ở những dự án khác, hình ảnh được tạo bằng thuật toán. Vì chúng tôi đang ở trong blog Khoa học dữ liệu, cách thú vị để chúng tôi tạo một bộ sưu tập hình ảnh là cách thứ hai

Trong bài viết này, chúng ta sẽ tạo, sử dụng Python, một tập hợp các hình ảnh ngẫu nhiên với nhiều đặc điểm chung giữa chúng. Chúng tôi sẽ bắt đầu từ một số hình ảnh cơ sở mà chúng tôi sẽ thêm các phần tử lên trên để định cấu hình các hình ảnh cuối cùng sẽ tạo thành bộ sưu tập. Trong trường hợp này, chúng tôi sẽ sử dụng nền trên đó chúng tôi sẽ đặt các loại ký tự khác nhau trên đó chúng tôi sẽ thêm một đối tượng

Cuối cùng, chúng ta sẽ có một tập dữ liệu ảnh, trong đó mỗi ảnh sẽ có các thuộc tính cụ thể. Ví dụ: một tên cướp biển trong sa mạc với một chiếc bánh rán hoặc một con quái vật trong rừng với một chiếc chìa khóa

Một tên cướp biển trong rừng với một mỏ neo. [Nền rừng] của George Hodan. [Cướp biển và mỏ neo] của craftpix. mạng lưới

Vì mục tiêu không phải là tạo ra nghệ thuật, tôi sẽ lấy nghệ thuật pixel được phân phối tự do làm cơ sở. Tôi sẽ sử dụng những hình ảnh này làm cơ sở để tạo ra hàng trăm hình ảnh phái sinh. Như một bài tập thú vị, bạn có thể chọn một số hình ảnh khác nhau và tạo tập dữ liệu hoàn toàn khác của riêng mình

Các thuộc tính tôi sẽ sử dụng sẽ có ba loại. nền, nhân vật và các đối tượng. Đối với mỗi tính năng, tôi sẽ đặt phân phối xác suất ở dạng phần trăm để xác định mức độ phổ biến của từng tính năng. Vui lòng chơi với các tham số để tạo các loại bộ dữ liệu khác nhau. Ví dụ: tập dữ liệu trong đó 99% hình ảnh sử dụng một tính năng và 1% khác. Bằng cách thực hiện các thí nghiệm thuộc loại này và tạo mô hình dự đoán trên chúng, bạn có thể học được rất nhiều điều

Phân phối xác suất của tài sản

Để tạo tập dữ liệu của bài viết, tôi sẽ sử dụng phân phối thuộc tính này

Hình ảnh của tác giảLet's get to work

Bước đầu tiên là tìm những hình ảnh sẽ được sử dụng làm cơ sở. Sử dụng nhiều trang web khác nhau, tôi đã chọn một số hình ảnh để làm cơ sở. Tiêu chí chính để lựa chọn hình ảnh là chúng có thể được sửa đổi và phân phối miễn phí theo giấy phép của chúng. Bạn có thể tải xuống tất cả các hình ảnh được sử dụng trong kho lưu trữ này

Khi các hình ảnh đã được chọn, chúng ta có thể bắt đầu lập trình trình tạo hình ảnh theo thuật toán. Để tạo hình ảnh, tôi sẽ sử dụng Python cùng với thư viện Gối. Đây là kịch bản cơ bản để tạo ra một hình ảnh

from os import path, mkdirfrom PIL import Imageoutput_folder = "generated"if not path.exists[output_folder]:mkdir[output_folder]background_file = path.join["backgrounds", "forest.png"]background_image = Image.open[background_file]output_file = path.join[output_folder, "generated1.png"]background_image.save[output_file]

Đầu tiên, thư mục “đã tạo” được tạo để lưu các tệp đã tạo. Nếu thư mục đã tồn tại, chúng tôi không làm gì cả. Chúng tôi tải một trong các hình nền và lưu nó vào thư mục "đã tạo". Chúng tôi đã thực hiện thao tác đầu tiên với hình ảnh. Bây giờ chỉ là vấn đề thêm nhiều yếu tố lên trên cho đến khi hình ảnh cuối cùng được tạo ra

Nền ví dụ [Nền nông thôn] của Dawn Hudson

Chúng tôi sẽ cung cấp kích thước cố định cho nền để tất cả các hình ảnh được tạo có cùng kích thước. Để đơn giản hóa công việc, tôi đã thu nhỏ hình nền lớn nhất thành cùng kích thước với hình nền nhỏ nhất trong số chúng. Tôi chưa thu nhỏ các ký tự vì mục tiêu của dự án này là hoạt động được chứ không phải đẹp. Một số đối tượng tôi đã thu nhỏ vì chúng lớn hơn đáng kể so với những đối tượng khác và chúng nằm ngoài hình ảnh

Hình nền được sử dụng có kích thước 1920x1078 px sau khi được thu nhỏ

Trên các ký tự và đối tượng, phép biến đổi duy nhất được thực hiện là loại bỏ các lề vì mỗi hình ảnh có các lề khác nhau ở mỗi bên. Điều này làm cho ngay cả khi đặt chúng ở cùng một vị trí, một số trong số chúng cao hơn hoặc lệch về bên phải hơn những cái khác

Công việc trở nên phức tạp hơn một chút khi thêm các ký tự và đối tượng lên trên nền. Bây giờ chúng ta phải xác định vị trí mà chúng ta muốn đặt các ký tự và kích thước của chúng. Để xác định vị trí, chúng tôi có một số tùy chọn

- xác định vị trí cố định cho tất cả hình ảnh
- xác định vị trí cố định cho từng loại ký tự/từng loại phong cảnh
- sắp xếp ngẫu nhiên vị trí. Nếu chúng tôi chọn cái sau, chúng tôi nên xác định một số giới hạn mà chúng tôi không muốn hình ảnh xuất hiện, chúng tôi không muốn hình ảnh được đặt trên đường viền và chỉ một phần nhỏ của nó được nhìn thấy.

Nhân vật đi ra khỏi rìa. [Nền rừng] của George Hodan. [Quái vật và chiếc rương] của craftpix. mạng lưới

Với các đối tượng cũng sẽ như vậy, chúng ta sẽ phải xác định vị trí đặt chúng tùy thuộc vào vị trí của nhân vật hoặc vị trí được xác định trước trên nền. Đối với tập dữ liệu này, tôi đã quyết định đặt các đối tượng ở bên phải của các ký tự

Gối sử dụng hệ tọa độ có gốc tọa độ ở góc trên bên trái của hình ảnh. Như đã thấy trong hình ảnh này

Hình ảnh của tác giả

Để đơn giản hóa công việc, tôi đã quyết định đặt tất cả các ký tự ở cùng một vị trí cố định trên nền. Tôi đã xác định vị trí là một điểm được căn giữa theo chiều ngang ở dưới cùng của hình ảnh. Kích thước của hình chữ nhật nhỏ, h và w là chiều cao và chiều rộng của ký tự. Điểm được đánh dấu màu đen là điểm chúng ta phải tính toán để cho Gối biết vị trí đặt ký tự trong ảnh

Hình ảnh của tác giả

Điểm này có thể tính theo công thức sau, trong đó 1920 là độ rộng của nền ta chia 2 để tìm trung điểm. 1000 gần đúng với 1078 để chừa lại một số lề giữa chân của nhân vật và phần dưới cùng của hình ảnh

Hình ảnh của tác giả

Để đặt các đối tượng bên phải ký tự, tôi sử dụng công thức tương tự, trong trường hợp này tôi thêm lề m để đối tượng không chạm vào ký tự. Giá trị của m phù hợp với tôi là 30 px. Chú ý, h và w trong trường hợp này là chiều cao và chiều rộng của ký tự, không phải của đối tượng vì chúng ta định vị bên phải ký tự

Hình ảnh của tác giả

Hình ảnh của tác giả

Tất cả những tính toán này được dịch thành mã trở thành thế này

def generate_image[background, character, object, file_name]:  background_file = path.join["backgrounds", f"{background}.png"]  background_image = Image.open[background_file]  #Create character  character_file = path.join["characters", f"{character}.png"]  character_image = Image.open[character_file]  coordinates = [int[1920/2-character_image.width/2], int[1000-character_image.height]] #x, y  background_image.paste[character_image, coordinates, mask=character_image]  #Create object  if object != "none":  object_file = path.join["objects", f"{object}.png"]  object_image = Image.open[object_file]  coordinates = [int[1920/2+character_image.width/2+30], int[1000-object_image.height]] #x, y  background_image.paste[object_image, coordinates, mask=object_image]  output_file = path.join[output_folder, f"{file_name}.png"]  background_image.save[output_file]
Ok nhưng… Đưa tôi dữ liệu

Đồng thời chúng tôi tạo hình ảnh, chúng tôi cũng sẽ đăng ký chúng trong cơ sở dữ liệu cùng với các đặc điểm của chúng. Chúng tôi sẽ sử dụng pandas để đăng ký và chúng tôi sẽ lưu dữ liệu vào tệp CSV

Chúng tôi tạo DataFrame không có dữ liệu, chỉ đặt tên cho các cột. Mỗi khi chúng tôi tạo một hình ảnh, một hàng mới sẽ được thêm vào DataFrame. Cuối cùng, khi tất cả các hình ảnh đã được tạo, CSV sẽ được lưu. Biến num là một bộ đếm tuần tự được sử dụng để đặt tên cho các hình ảnh. Ví dụ, các hình ảnh được tạo sẽ được đặt tên là tạo1, tạo2, tạo2894,…

Cần lưu tên file ảnh để biết các thông số này tương ứng với file nào

df = pd.DataFrame[columns = ["background", "character", "object", "generated image"]]for … …. ….  #Code to generate image  data = [background, character, object, f"generated{num}"]  s = pd.Series[data, index=df.columns]  df = df.append[s, ignore_index=True]df.to_csv['data.csv', index=False]

Tôi sẽ nhận được bao nhiêu hình ảnh?

Bạn có thể tính tổng số hình ảnh có thể bằng một công thức đơn giản. Chỉ cần nhân số thuộc tính có thể có trong mỗi danh mục với nhau. Trong trường hợp của chúng tôi, 4 hình nền * 5 ký tự * 11 đối tượng = 220 hình ảnh

Để tạo tất cả các hình ảnh có thể, chúng tôi sẽ sử dụng mã này. Trước tiên, chúng tôi xác định tất cả các giá trị có thể có cho từng tham số, sau đó chúng tôi lặp lại chúng

backgrounds = ["countryside", "desert", "forest", "glacial"]characters = ["mage", "warrior", "pirate", "monster", "toadking"]objects = ["none", "barrel", "anchor", "axe", "bomb", "key", "chest", "bananas", "cupcake", "donut", "heart",]def generate_all_imgs[]:  num = 0  df = pd.DataFrame[columns = ["background", "character", "object", "generated image"]]  for background in backgrounds:    for character in characters:      for object in objects:        generate_image[background, character, object, f"generated{num}"]        data = [background, character, object, f"generated{num}"]        s = pd.Series[data, index=df.columns]        df = df.append[s, ignore_index=True]        num += 1  df.to_csv['data.csv', index=False]

ngẫu nhiên hóa

Khi tạo hình ảnh, chúng tôi đã thấy cách tạo tất cả các hình ảnh có thể. Trong trường hợp này, chúng tôi có thể tạo tất cả chúng vì chúng rất ít, nhưng nếu chúng tôi tăng số lượng tham số hoặc số khả năng của từng tham số, thì có thể số lượng hình ảnh tạo ra là rất lớn

Với mã này, chúng tôi sẽ tạo ra một số hình ảnh nhất định [total_imgs]. Để quyết định sử dụng các tính năng nào trong mỗi hình ảnh, chúng tôi sẽ sử dụng cơ hội. Lưu ý rằng có thể cùng một hình ảnh được tạo nhiều lần và điều này sẽ phổ biến trong trường hợp các tham số có khả năng nhất [rất có thể là nền với ký tự có khả năng nhất và đối tượng có khả năng nhất, trong trường hợp của chúng tôi, đó có thể là một pháp sư trong một

Chúng tôi sẽ sử dụng xác suất được xác định trong bảng trên cho từng thuộc tính và sử dụng ngẫu nhiên của Numpy. chức năng lựa chọn, chúng tôi sẽ chọn một thuộc tính có tính đến thuộc tính nào có khả năng nhất

def generate_random_imgs[total_imgs]:  df = pd.DataFrame[columns = ["background", "character", "object", "generated image"]]  for num in range[total_imgs]:    background = np.random.choice[np.arange[0,len[backgrounds]], p=[0.3, 0.3, 0.3, 0.1]]    background = backgrounds[background]    character = np.random.choice[np.arange[0,len[characters]], p=[0.4, 0.3, 0.2, 0.095, 0.005]]    character = characters[character]    object = np.random.choice[np.arange[0,len[objects]], p=[0.3, 0.2, 0.1, 0.1, 0.1, 0.05, 0.05, 0.04, 0.03, 0.025, 0.005]]    object = objects[object]    generate_image[background, character, object, f"generated{num}"]    data = [background, character, object, f"generated{num}"]    s = pd.Series[data, index=df.columns]    df = df.append[s, ignore_index=True]  df.to_csv['data.csv', index=False]

Cẩn thận không sử dụng số quá cao vì quá trình tạo có thể mất hàng giờ và hình ảnh được tạo có thể chiếm nhiều GB

Sự kết luận

Chúng tôi đã tạo một chương trình nhỏ và cơ bản để tạo bộ dữ liệu hình ảnh tổng hợp từ các hình ảnh cơ bản. Với bộ dữ liệu này, chúng ta có thể bắt đầu đào tạo một mạng lưới thần kinh để phân loại hình ảnh theo loại nền hoặc theo loại ký tự

Ngoài ra với tập lệnh này, chúng tôi có cơ sở để làm những việc phức tạp hơn, chúng tôi có thể thêm các góc quay cho các ký tự, làm cho chúng có kích thước khác nhau, thay đổi màu sắc, v.v…

Bạn có thể sử dụng trình tạo tập dữ liệu này làm sân chơi thử nghiệm cho các kỹ thuật tăng cường dữ liệu, ví dụ: bạn có thể tạo hình ảnh mới trong đó ký tự ở vị trí khác thay vì luôn giống nhau. Bạn có thể tạo hình ảnh trong đó nhân vật hoặc đối tượng được xoay, v.v...

Chủ Đề