예제 #1
0
파일: Image.cpp 프로젝트: alinas/Halide
p::object image_to_python_object(const h::Image<> &im) {
    PyObject *obj = nullptr;
    if (im.type() == h::UInt(8)) {
        p::manage_new_object::apply<h::Image<uint8_t> *>::type converter;
        obj = converter(new h::Image<uint8_t>(im));
    } else if (im.type() == h::UInt(16)) {
        p::manage_new_object::apply<h::Image<uint16_t> *>::type converter;
        obj = converter(new h::Image<uint16_t>(im));
    } else if (im.type() == h::UInt(32)) {
        p::manage_new_object::apply<h::Image<uint32_t> *>::type converter;
        obj = converter(new h::Image<uint32_t>(im));
    } else if (im.type() == h::Int(8)) {
        p::manage_new_object::apply<h::Image<int8_t> *>::type converter;
        obj = converter(new h::Image<int8_t>(im));
    } else if (im.type() == h::Int(16)) {
        p::manage_new_object::apply<h::Image<int16_t> *>::type converter;
        obj = converter(new h::Image<int16_t>(im));
    } else if (im.type() == h::Int(32)) {
        p::manage_new_object::apply<h::Image<int32_t> *>::type converter;
        obj = converter(new h::Image<int32_t>(im));
    } else if (im.type() == h::Float(32)) {
        p::manage_new_object::apply<h::Image<float> *>::type converter;
        obj = converter(new h::Image<float>(im));
    } else if (im.type() == h::Float(64)) {
        p::manage_new_object::apply<h::Image<double> *>::type converter;
        obj = converter(new h::Image<double>(im));
    } else {
        throw std::invalid_argument("image_to_python_object received an Image of unsupported type.");
    }

    return p::object(p::handle<>(obj));
}
예제 #2
0
int main(int argc, char **argv) {

  Halide::Func cell("cell");
  Halide::Var x, y;
  cell(x, y) = 0;
  cell(2, 1) = 1;
  cell(3, 2) = 1;
  cell(1, 3) = 1;
  cell(2, 3) = 1;
  cell(3, 3) = 1;

  Halide::Image<int32_t> output;
  output = cell.realize(NX,NY);

  Halide::ImageParam input(Halide::Int(32), 2); // int32_t 2D


  Halide::Func cell2;
  cell2(x,y)=input(x,y)+1;
  Halide::Func nbd("nbd");
  Halide::Func bc("bc");

  for (int t=0; t<10; ++t) {
    Halide::Image<int32_t> output = cell.realize(NX,NY);
    for (int j = 0; j < output.height(); j++) {
      for (int i = 0; i < output.width(); i++) {
	printf("%1d", output(i, j));
      }
      printf("\n");
    }
    printf("\n");

    bc(x,y)=select((x>=0)&&(x<NX)&&(y>=0)&&(y<NY)
		   ,output(min(NX-1,max(x,0)),min(NY-1,max(y,0))),0);
    
    nbd(x,y)=-bc(x,y);
    // staged programming!
    for(int dy=-1; dy<=1; ++dy) {   
      for(int dx=-1; dx<=1; ++dx) {
	nbd(x,y)+=bc(x+dx,y+dy);
      }
    }

    cell(x,y)=select((bc(x,y)==1&&nbd(x,y)==3)||(bc(x,y)==1&&nbd(x,y)==2)
		     || (bc(x,y)==0&&nbd(x,y)==3)
		     ,1,0);
  }

  return 0;
}
예제 #3
0
void NamedWindow::showImage2D(Halide::Image<uint8_t> im)
{
	static Halide::Func convert("convertToMat2D");
	static Halide::ImageParam ip(Halide::UInt(8), 2);
	static Halide::Var x, y;

	if (!convert.defined())
	{
		convert(x, y) = ip(x, y);
		convert.vectorize(x, 4).parallel(y, 4);
	}

	ip.set(im);
	cv::Mat mat(im.height(), im.width(), CV_8UC1, cv::Scalar(0));
	convert.realize(Halide::Buffer(Halide::UInt(8), im.width(), im.height(), 0, 0, mat.data));
	cv::imshow(name, mat);
}
예제 #4
0
void NamedWindow::showImage3D(Halide::Image<float> im)
{
	static Halide::Func convert("convertToMat3D");
	static Halide::ImageParam ip(Halide::Float(32), 3);
	static Halide::Var x, y, c;

	if (!convert.defined())
	{
		convert(c, x, y) = Halide::cast<uint8_t>(ip(x, y, 2 - c) * 255);
		convert.vectorize(x, 4).parallel(y, 4);
	}

	ip.set(im);
	cv::Mat mat(im.height(), im.width(), CV_8UC3, cv::Scalar(0));
	convert.realize(Halide::Buffer(Halide::UInt(8), im.channels(), im.width(), im.height(), 0, mat.data));
	cv::imshow(name, mat);
}
예제 #5
0
int sobel_example(int argc, const char **argv) {
    Halide::Image<uint8_t> input = load<uint8_t>(argv[0]);
    Halide::Var x,y,c;
    Halide::Func padded;
    padded(x,y) = input(clamp(x, 0, input.width()-1), clamp(y, 0, input.height()-1));

    Halide::Image<uint8_t> sobel_output(input.width(), input.height());

    // smooth the image
    // Halide::Func gaussian = gaussian_3x3(padded, true);

    // calculate the horizontal and vertical gradients (GX, Gy)
    std::pair<Halide::Func, Halide::Func> sobel = sobel_3x3(padded, true);
    Halide::Func Gx, Gy;
    Gx(x,y) = AS_UINT8(sobel.first(x,y));
    Gx.realize(sobel_output);
    save(sobel_output, "output/sobel_gx.png");

    Gy(x,y) = AS_UINT8(sobel.second(x,y));
    Gy.realize(sobel_output);
    save(sobel_output, "output/sobel_gy.png");

    // Calculate gradient magnitudes and scale them to image intensity 
    // Described in http://patrick-fuller.com/gradients-image-processing-for-scientists-and-engineers-part-3/
    Halide::RDom r(input);
     
    Halide::Func maxpix, minpix, luminosity, mag, mag_uint8;

    // calculate the {min,max} luminosity values of the original grayscale image
    Halide::Image<int32_t> max_out, min_out;
    maxpix(x) = 0; minpix(x) = 0;
    maxpix(0) = max(input(r.x, r.y), maxpix(0));
    minpix(0) = min(input(r.x, r.y), minpix(0));
    max_out = maxpix.realize(1);
    min_out = minpix.realize(1);

    // calculate the magnitude of Gx, Gy
    mag = grad_magnitude(sobel.first, sobel.second);
    // scale the magnitude by the luminosity range 
    luminosity(x,y) = 255.0f * ((mag(x,y)-min_out(0)) / (max_out(0)-min_out(0)));
    TO_2D_UINT8_LAMBDA(luminosity).realize(sobel_output);
    save(sobel_output, "output/sobel_mag.png");

    printf("%s DONE\n", __func__);
    return EXIT_SUCCESS;
}
예제 #6
0
void NamedWindow::showImage(Halide::Image<float> im)
{
	switch (im.dimensions())
	{
	case 2:
		showImage2D(im);
		break;
	case 3:
		showImage3D(im);
		break;
	default:
		throw std::exception("Image must be either 2- or 3-dimensional.");
	}
}
예제 #7
0
파일: Image.cpp 프로젝트: alinas/Halide
std::string image_repr(const h::Image<T> &image) {
    std::string repr;

    h::Type t = halide_type_of<T>();
    std::string suffix = "_???";
    if (t.is_float()) {
        suffix = "_float";
    } else if (t.is_int()) {
        suffix = "_int";
    } else if (t.is_uint()) {
        suffix = "_uint";
    } else if (t.is_bool()) {
        suffix = "_bool";
    } else if (t.is_handle()) {
        suffix = "_handle";
    }

    boost::format f("<halide.Image%s%i; element_size %i bytes; "
                    "extent (%i %i %i %i); min (%i %i %i %i); stride (%i %i %i %i)>");

    repr = boost::str(f % suffix % t.bits() % t.bytes() % image.extent(0) % image.extent(1) % image.extent(2) % image.extent(3) % image.min(0) % image.min(1) % image.min(2) % image.min(3) % image.stride(0) % image.stride(1) % image.stride(2) % image.stride(3));

    return repr;
}
int main(int argc, char **argv) {

    // This program defines a single-stage imaging pipeline that
    // brightens an image.

    // First we'll load the input image we wish to brighten.
    Halide::Image<uint8_t> input = load<uint8_t>("../apps/images/rgb.png");

    // Next we define our Func object that represents our one pipeline
    // stage.
    Halide::Func brighter;

    // Our Func will have three arguments, representing the position
    // in the image and the color channel. Halide treats color
    // channels as an extra dimension of the image.
    Halide::Var x, y, c;

    // Normally we'd probably write the whole function definition on
    // one line. Here we'll break it apart so we can explain what
    // we're doing at every step.

    // For each pixel of the input image.
    Halide::Expr value = input(x, y, c);

    // Cast it to a floating point value.
    value = Halide::cast<float>(value);

    // Multiply it by 1.5 to brighten it. Halide represents real
    // numbers as floats, not doubles, so we stick an 'f' on the end
    // of our constant.
    value = value * 1.5f;

    // Clamp it to be less than 255, so we don't get overflow when we
    // cast it back to an 8-bit unsigned int.
    value = Halide::min(value, 255.0f);

    // Cast it back to an 8-bit unsigned integer.
    value = Halide::cast<uint8_t>(value);

    // Define the function.
    brighter(x, y, c) = value;

    // The equivalent one-liner to all of the above is:
    //
    // brighter(x, y, c) = Halide::cast<uint8_t>(min(input(x, y, c) * 1.5f, 255));
    //
    // In the shorter version:
    // - I skipped the cast to float, because multiplying by 1.5f does
    //   that automatically.
    // - I also used integer constants in clamp, because they get cast
    //   to match the type of the first argument.
    // - I left the Halide:: off clamp. It's unnecessary due to Koenig
    //   lookup.

    // Remember. All we've done so far is build a representation of a
    // Halide program in memory. We haven't actually processed any
    // pixels yet. We haven't even compiled that Halide program yet.

    // So now we'll realize the Func. The size of the output image
    // should match the size of the input image. If we just wanted to
    // brighten a portion of the input image we could request a
    // smaller size. If we request a larger size Halide will throw an
    // error at runtime telling us we're trying to read out of bounds
    // on the input image.
    Halide::Image<uint8_t> output = brighter.realize(input.width(), input.height(), input.channels());

    // Save the output for inspection. It should look like a bright parrot.
    save(output, "brighter.png");

    printf("Success!\n");
    return 0;
}
예제 #9
0
int main(int argc, char **argv) {

    // This program defines a single-stage imaging pipeline that
    // outputs a grayscale diagonal gradient.

    // A 'Func' object represents a pipeline stage. It's a pure
    // function that defines what value each pixel should have. You
    // can think of it as a computed image.
    Halide::Func gradient;

    // Var objects are names to use as variables in the definition of
    // a Func. They have no meaning by themselves.
    Halide::Var x, y;

    // We typically use Vars named 'x' and 'y' to correspond to the x
    // and y axes of an image, and we write them in that order. If
    // you're used to thinking of images as having rows and columns,
    // then x is the column index, and y is the row index.

    // Funcs are defined at any integer coordinate of its variables as
    // an Expr in terms of those variables and other functions.
    // Here, we'll define an Expr which has the value x + y. Vars have
    // appropriate operator overloading so that expressions like
    // 'x + y' become 'Expr' objects.
    Halide::Expr e = x + y;

    // Now we'll add a definition for the Func object. At pixel x, y,
    // the image will have the value of the Expr e. On the left hand
    // side we have the Func we're defining and some Vars. On the right
    // hand side we have some Expr object that uses those same Vars.
    gradient(x, y) = e;

    // This is the same as writing:
    //
    //   gradient(x, y) = x + y;
    //
    // which is the more common form, but we are showing the
    // intermediate Expr here for completeness.

    // That line of code defined the Func, but it didn't actually
    // compute the output image yet. At this stage it's just Funcs,
    // Exprs, and Vars in memory, representing the structure of our
    // imaging pipeline. We're meta-programming. This C++ program is
    // constructing a Halide program in memory. Actually computing
    // pixel data comes next.

    // Now we 'realize' the Func, which JIT compiles some code that
    // implements the pipeline we've defined, and then runs it.  We
    // also need to tell Halide the domain over which to evaluate the
    // Func, which determines the range of x and y above, and the
    // resolution of the output image. Halide.h also provides a basic
    // templatized Image type we can use. We'll make an 800 x 600
    // image.
    Halide::Image<int32_t> output = gradient.realize(800, 600);

    // Halide does type inference for you. Var objects represent
    // 32-bit integers, so the Expr object 'x + y' also represents a
    // 32-bit integer, and so 'gradient' defines a 32-bit image, and
    // so we got a 32-bit signed integer image out when we call
    // 'realize'. Halide types and type-casting rules are equivalent
    // to C.

    // Let's check everything worked, and we got the output we were
    // expecting:
    for (int j = 0; j < output.height(); j++) {
        for (int i = 0; i < output.width(); i++) {
            // We can access a pixel of an Image object using similar
            // syntax to defining and using functions.
            if (output(i, j) != i + j) {
                printf("Something went wrong!\n"
                       "Pixel %d, %d was supposed to be %d, but instead it's %d\n",
                       i, j, i+j, output(i, j));
                return -1;
            }
        }
    }

    // Everything worked! We defined a Func, then called 'realize' on
    // it to generate and run machine code that produced an Image.
    printf("Success!\n");

    return 0;
}
예제 #10
0
파일: Image.cpp 프로젝트: alinas/Halide
void image_copy_to_host(h::Image<T> &im) {
    im.copy_to_host();
}
예제 #11
0
파일: Image.cpp 프로젝트: alinas/Halide
void image_set_min4(h::Image<T> &im, int m0, int m1, int m2, int m3) {
    im.set_min(m0, m1, m2, m3);
}
예제 #12
0
파일: Image.cpp 프로젝트: alinas/Halide
void image_set_min3(h::Image<T> &im, int m0, int m1, int m2) {
    im.set_min(m0, m1, m2);
}
예제 #13
0
파일: Image.cpp 프로젝트: alinas/Halide
void image_set_min2(h::Image<T> &im, int m0, int m1) {
    im.set_min(m0, m1);
}
예제 #14
0
파일: Image.cpp 프로젝트: alinas/Halide
void image_set_min1(h::Image<T> &im, int m0) {
    im.set_min(m0);
}