sample.h
typedef unsigned int uint32; typedef unsigned char uint8; typedef struct simple_image_t { uint32 rows; uint32 cols; uint8 * imgdata; } simple_image; #ifdef SAMPLE_EXPORT # define SAMPLE_API __declspec(dllexport) #else # define SAMPLE_API __declspec(dllimport) #endif SAMPLE_API void some_func(const simple_image * si);
sample.c
#include <stdio.h>
#define SAMPLE_EXPORT
#include "sample.h"
void some_func(const simple_image* si)
{
uint32 i,j;
printf(
"rows = %d\n"
"cols = %d\n",
si->rows,si->cols);
/* Dump a simple map of the image data */
for(i = 0; i < si->rows; i++)
{
for(j = 0; j < si->cols; j++)
{
if(si->imgdata[i * si->rows + j] < 0x80)
printf(" ");
else
printf("*");
}
printf("\n");
}
}
sample.i
%module sample
%begin %{
#pragma warning(disable:4100 4127 4706)
%}
%{
#include "sample.h"
%}
%include <windows.i>
%typemap(in) uint8* (char* buffer, Py_ssize_t length) {
PyString_AsStringAndSize($input,&buffer,&length);
$1 = (uint8*)buffer;
}
%include "sample.h"
example.py
from PIL import Image import sample im = Image.open('sample.gif') im = im.convert('L') si = sample.simple_image() si.rows, si.cols = im.size s = im.tostring() # Must keep a reference si.imgdata = s sample.some_func(si)
With this quick example I haven't determined how the typemap should correctly increment the reference count of the string object. Note that the above code could crash if the following code were used:
si.imgdata = im.tostring()
May be you could convert the image to a char array using the array
module, and then, from swig, memcpy the data to your C array.
import array
imagar = array.array('B', pil_image.getdata())
(mem, length) = imagar.buffer_info()
swig_wrapper.py_copy(img, mem, length)
being py_copy
something like:
void py_copy(simple_image * img, uint32 mem, uint32 length) {
memcpy((void * ) img - > imgdata, (void * ) mem, length);
}
1 week ago Jun 30, 2011 · I've got a library that takes in a very simple C image structure: // Represents a one-channel 8-bit image typedef struct simple_image_t { uint32 rows; uint32 cols; uint8 *imgdata; } ,I've got a library that takes in a very simple C image structure:, 6 days ago Marshaling a Python PIL Image using SWIG // Represents a one-channel 8-bit image. typedef struct simple_image_t ... for pixel in pil_image.getdata(): swig_wrapper.py_set_simple_image(img, pos, pixel) pos += 1 # Call some library method that accepts a simple_image* return swig_wrapper.some_image_method(img) finally: # Clean up … ,What are my options in terms of speed? Are there quicker ways of marshaling the pixel data from a PIL image to this simple image structure? Has someone already done this and my Google skills are just that bad? Am I just boned and soon will need to learn the internals of PIL?
// Represents a one-channel 8-bit image typedef struct simple_image_t { uint32 rows; uint32 cols; uint8 *imgdata; } simple_image;
// Represents a one-channel 8-bit image typedef struct simple_image_t {uint32 rows;uint32 cols;uint8 *imgdata;} simple_image;
// Allows python to easily create and initialize this structure simple_image* py_make_simple_image(uint32 width, uint32 height) {simple_image* img = new simple_image();img->rows = height;img->cols = width;img->imgdata = new uint8[height * width];return img;} // Allows python to set a particular pixel value void py_set_simple_image(simple_image* img, uint32 pos, uint8 val) {img->imgdata[pos] = val;}
# Make sure it 's an 8-bit image if pil_image.mode != "L":pil_image = pil_image.convert("L") # Create the simple image structure (width, height) = pil_image.size img = swig_wrapper.py_make_simple_image(width, height) try:# Copy the image data into the simple image structurepos = 0for pixel in pil_image.getdata(): swig_wrapper.py_set_simple_image(img, pos, pixel) pos += 1# Call some library method that accepts a simple_image*return swig_wrapper.some_image_method(img) finally:# Clean up the simple image structureswig_wrapper.py_destroy_simple_image(img)
typedef unsigned int uint32; typedef unsigned char uint8; typedef struct simple_image_t { uint32 rows; uint32 cols; uint8 * imgdata; } simple_image; #ifdef SAMPLE_EXPORT # define SAMPLE_API __declspec(dllexport) #else # define SAMPLE_API __declspec(dllimport) #endif SAMPLE_API void some_func(const simple_image * si);
#include <stdio.h> #define SAMPLE_EXPORT #include "sample.h" void some_func(const simple_image* si) {uint32 i,j;printf( "rows = %d\n" "cols = %d\n", si->rows,si->cols);/* Dump a simple map of the image data */for(i = 0;i <si->rows;i++){ for(j = 0;j <si->cols;j++) { if(si->imgdata[i * si->rows + j] <0x80)printf(" ");elseprintf("*"); } printf("\n");} }
The following script loads an image, rotates it 45 degrees, and displays it using an external viewer (usually xv on Unix, and the Paint program on Windows).,Examples Open, rotate, and display an image (using the default viewer) Create thumbnails ,Split this image into individual bands. This method returns a tuple of individual image bands from an image. For example, splitting an “RGB” image creates three new images each containing a copy of one of the original bands (red, green, blue).,A lookup table, containing 256 (or 65536 if self.mode==”I” and mode == “L”) values per band in the image. A function can be used instead, it should take a single argument. The function is called once for each possible pixel value, and the resulting table is applied to all bands of the image.
from PIL
import Image
with Image.open("hopper.jpg") as im:
im.rotate(45).show()
from PIL
import Image
import glob, os
size = 128, 128
for infile in glob.glob("*.jpg"):
file, ext = os.path.splitext(infile)
with Image.open(infile) as im:
im.thumbnail(size)
im.save(file + ".thumbnail", "JPEG")
out = image1 * (1.0 - alpha) + image2 * alpha
from PIL
import Image
import numpy as np
im = Image.open("hopper.jpg")
a = np.asarray(im)
im = Image.fromarray(a)
from PIL import Image import numpy as np a = np.full((1, 1), 300) im = Image.fromarray(a, mode = "L") im.getpixel((0, 0)) # 44 im = Image.fromarray(a, mode = "RGB") im.getpixel((0, 0)) #(44, 1, 0)
updated 2018-04-23 10:18:19 -0500 , asked 2018-04-19 17:36:18 -0500 , Asked: 2018-04-19 17:36:18 -0500 , Last updated: Apr 25 '18
This code sets up a new Mat from a void* pointer (called ptr):
Mat frame_content = Mat(480, 640, CV_16UC1, ptr).clone();
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <mutex>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
mutex rw_ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
rw_ids.lock();
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
rw_ids.unlock();
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
rw_ids.unlock();
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
rw_ids.lock();
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
delete[] ci->second;
ids.erase(ci);
rw_ids.unlock();
return 0;
}
}
rw_ids.unlock();
return 1;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype = np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}
import myLib import cv2 import numpy as np imgPtr = myLib.GetImgBuffer(img1, cols1, rows1) numpy_array = np.frombuffer(imgPtr, dtype=np.uint8) numpy_array.shape = (rows1, cols1)
//assume: rows1 = cols1 = 1024
//change the image in python
dst = np.ones((1024, 1024), dtype = np.uint8)
//update data in the buffer
np.copyto(numpy_array, dst) //IS THIS CORRECT FOR UPDATING THE MEMORY IN THE BUFFER??
numpy_array.shape = dst.shape
//create another numpy array from the updated buffer
numpy_array2 = np.frombuffer(imgPtr, dtype = np.uint8)
numpy_array2.shape = numpy_array.shape // this array display the correct change but when we pick up
//the change in c++, only ~ quarter of the image is changed)
cv2.imshow('img - retrieve image from updated buffer & display in Python', numpy_array2)
cv2.waitKey(0)
To expose the shared python buffer from C++ side:
PyObject *: GetBufferPtr(Image img, long width, long height) {
.....
Py_buffer pybuffer; //where buf points to a void* for image pixel
int res = PyBuffer_FillInfo( & pybuffer, 0, buf, val, false, PyBUF_CONTIG);..
return PyMemoryView_FromBuffer( & pybuffer);
}
To retrieve image buffer from Python's side and update the buffer from Python side:
import myLib
import cv2
import numpy as np
imgPtr = myLib.GetImgBuffer(img1, cols1, rows1)
numpy_array = np.frombuffer(imgPtr, dtype = np.uint8) //for one byte integer image
numpy_array.shape = (rows1, cols1)
//change the image in python
dst = np.ones((rows1, cols1), dtype = np.uint8)
//update data in the buffer
np.copyto(numpy_array, dst) //update the buffer
numpy_array.shape = dst.shape
Last Updated On: December 02, 2020
You can install Pillow with pip
as shown:
python3 - m pip install--upgrade pip
python3 - m pip install--upgrade Pillow
To load an image from a file, we use the open()
function in the Image
module, passing it the path to the image.
from PIL
import Image
image = Image.open('demo_image.jpg')
After obtaining an Image
object, you can now use the methods and attributes defined by the class to process and manipulate it. Let's start by displaying the image. You can do this by calling the show()
method on it. This displays the image on an external viewer (usually Preview on macOS, xv on Unix, and the Paint program on Windows).
image.show()
When you are done processing an image, you can save it to a file with the save()
method, passing in the name that will be used to label the image file. When saving an image, you can specify a different extension from its original, and the saved image will be converted to the specified format.
image = Image.open('demo_image.jpg')
image.save('new_image.png')
To resize an image, you call the resize()
method on it, passing in a two-integer tuple argument representing the width and height of the resized image. The function doesn't modify the used image; it instead returns another Image with the new dimensions.
image = Image.open('demo_image.jpg') new_image = image.resize((400, 400)) new_image.save('image_400.jpg') print(image.size) # Output: (1920, 1280) print(new_image.size) # Output: (400, 400)
While working on images using python image processing library, there are instances where you need to flip an existing image to get some more insights out of it, to enhance its visibility or because of your requirement.,To display the image, pillow library is using an image class within it. The image module inside pillow package contains some important inbuilt functions like, load images or create new images, etc.,Cropping is one of the important operations of the image processing to remove unwanted portions of an image as well as to add required features to an image. It is widely used process in web applications, for uploading an image.,In today’s digital world, we come across lots of digital images. In case, we are working with Python programming language, it provides lot of image processing libraries to add image processing capabilities to digital images.
To install pillow using pip, just run the below command in your command prompt −
python - m pip install pip python - m pip install pillow
Following example demonstrates the rotation of an image using python pillow −
from PIL
import Image
#Open image using Image module
im = Image.open("images/cuba.jpg")
#Show actual Image
im.show()
#Show rotated Image
im = im.rotate(45)
im.show()
This function is used to get the file name or the path of the image.
>>> image = Image.open('beach1.jpg') >>>
image.filename 'beach1.jpg'
It is used to get the pixel format used by the image. Typical values are “1”, “L”, “RGB” or “CMYK”.
>>> image.mode 'RGB'
It returns the tuple consist of height & weight of the image.
>>> image.size(1280, 721)