mattloper / chumpy

MIT License
195 stars 118 forks source link

Delete unused and deprecated import #48

Closed AndresCasado closed 1 year ago

AndresCasado commented 1 year ago

This makes Chumpy work with latest numpy version

BotScutters commented 1 year ago

I'm encountering this issue as well. @mattloper , are you able to review and merge this and release an update?

BotScutters commented 1 year ago

@AndresCasado I'm assuming that you ended up at this issue for the same reason as me, which was that loading SMPL models no longer works with Numpy >= 1.24.0 due to the usage of chumpy objects inside of the model pkl files. It turns out that the SMPL authors issued a fix for removing the chumpy dependency a few years ago. Not the absolute cleanest, but it works. The fix they offer is described here: https://github.com/vchoutas/smplx/blob/main/tools/README.md.

For your info and anyone else that comes across this, I created a Dockerfile that builds a minimal environment with Python2.7 and the required libraries to execute this action.

The Dockerfile:

FROM python:2.7

COPY . /app
WORKDIR /app

RUN pip install chumpy numpy scipy

CMD [ \
    "python", "dechumpy.py", \
    "--input-folder", "/app/input_folder", \
    "--output-folder", "/app/output_folder" \
]

I call it with a bash script like:

#!/bin/bash

# Build the dechumpy image
docker build -t dechumpy .

# Get the root of the Git repository
echo "Building dechumpy image..."
repo_root=$(git rev-parse --show-toplevel)

# Default input and output paths
INPUT_FOLDER=${1:-$repo_root/data/models/smpl}
OUTPUT_FOLDER=${2:-$repo_root/data/models/smpl_new}

# Run the dechumpy container
echo "Running dechumpy image..."
docker run -it --rm \
    -v "$INPUT_FOLDER:/app/input_folder" \
    -v "$OUTPUT_FOLDER:/app/output_folder" \
    dechumpy

And finally, I copied their clean_ch.py file and made a few modifications, as shown here. The main differences are that it saves the pickle files using protocol=2, which keeps them from blowing up to 3x larger, and I made the input a directory rather than set of files. dechumpy.py:

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

import argparse
import glob
import os
import os.path as osp
import pickle

import numpy as np

def clean_fn(fn, output_folder='output'):
    with open(fn, 'rb') as body_file:
        body_data = pickle.load(body_file)

    output_dict = {}
    for key, data in body_data.iteritems():
        if 'chumpy' in str(type(data)):
            output_dict[key] = np.array(data)
        else:
            output_dict[key] = data

    out_fn = osp.split(fn)[1]

    out_path = osp.join(output_folder, out_fn)
    with open(out_path, 'wb') as out_file:
        pickle.dump(output_dict, out_file, protocol=2)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--input-folder',
        dest='input_folder',
        required=False,
        type=str,
        default="input_folder",
        help='The path to the folder containing the models to be processed',
    )
    parser.add_argument(
        '--output-folder',
        dest='output_folder',
        required=False,
        type=str,
        default="output_folder",
        help='The path to the output folder',
    )

    args = parser.parse_args()

    input_folder = args.input_folder
    output_folder = args.output_folder
    if not osp.exists(output_folder):
        print('Creating directory: {}'.format(output_folder))
        os.makedirs(output_folder)

    # Get a list of .pkl files in the input folder
    input_models = glob.glob(os.path.join(input_folder, '*.pkl'))

    for input_model in input_models:
        clean_fn(input_model, output_folder=output_folder)

If you stick all of this in a directory and update the paths for your setup, you should be good. Hope this helps!

AndresCasado commented 1 year ago

@BotScutters Hi, yes, that's how I ended up finding the problem. I'll try to clean the files with that, thank you!