How do I restore attachment from files in wp-upload

Yes, you can do this. First set up a loop that loops through all the images in the upload directory. Then construct an array with the required data needed to create a new post of the type attachment:

$dir = new DirectoryIterator(wp_upload_dir()[0]);
foreach ($dir as $maybeFile) {
    if ($maybeFile->isFile()) {
        $filename = $maybeFile->getPathname();
        $wp_filetype = wp_check_filetype( $filename, null );
        $attachment = array(
            'post_mime_type' => $wp_filetype['type'],
            'post_title' => sanitize_file_name( $filename ),
            'post_content' => '',
            'post_status' => 'inherit'
        );
        $attach_id = wp_insert_attachment( $attachment, $filename );
        require_once( ABSPATH . 'wp-admin/includes/image.php' );
        $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
        wp_update_attachment_metadata( $attach_id, $attach_data );
    }
}

I used the DirectoryIterator php class: https://www.php.net/manual/en/class.directoryiterator.php

And this other stack overflow answer about how to upload an image that is at an arbitrary url to your upload directory: Programmatically adding images to media library