Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

Nội suy hình ảnh

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

Nội suy hình ảnh đề cập đến việc thay đổi kích thước của một hình ảnh kỹ thuật số. Nội suy là vấn đề xấp xỉ giá trị của hàm cho một điểm không được cung cấp trong một số không gian khi được đưa ra giá trị của hàm đó trong các điểm xung quanh (lân cận) điểm đó.

Nội suy hình ảnh có ba kỹ thuật chính:

1. Nội suy hàng xóm gần nhất

Nội suy lân cận gần nhất (còn được gọi là nội suy gần hoặc, trong một số bối cảnh, lấy mẫu điểm) là một phương pháp nội suy đa biến đơn giản trong một hoặc nhiều chiều. Thuật toán hàng xóm gần nhất chọn giá trị của điểm gần nhất và không xem xét các giá trị của các điểm lân cận, mang lại một nội suy liên tục. Thuật toán rất đơn giản để thực hiện và thường được sử dụng (thường cùng với mipmapping) trong kết xuất 3D thời gian thực để chọn các giá trị màu cho bề mặt kết cấu (Wikipedia).

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

2. Nội suy song phương

Nội suy song tuyến được thực hiện bằng cách sử dụng phép nội suy tuyến tính trước một hướng, và sau đó một lần nữa theo hướng khác. Nội suy song tuyến sử dụng các giá trị chỉ có 4 pixel gần nhất, nằm theo hướng chéo từ một pixel đã cho, để tìm các giá trị cường độ màu thích hợp của pixel đó (wikipedia).

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến
Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

3. Nội suy bicubic

Trong quá trình xử lý hình ảnh, phép nội suy bicubic thường được chọn trên nội suy song song hoặc lân cận gần nhất trong việc lấy mẫu hình ảnh, khi tốc độ không phải là vấn đề. Trái ngược với phép nội suy song song, chỉ đưa 4 pixel (2 × 2) vào tài khoản, nội suy bicubic xem xét 16 pixel (4 × 4) (Wikipedia)

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến
Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

Kết quả

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến
Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến
Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

Dự án nhân bản

$ git clone https://github.com/yasinEnigma/Image_Interpolation/
$ pip3 install -r requirements.txt
$ python3 main.py

Bỏ qua nội dung

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến

Nội suy song tuyến trên các hình ảnh được lưu trữ dưới dạng Python Numpy Ndarray

Nếu bạn đang làm việc trong việc xử lý hình ảnh và sử dụng Python làm ngôn ngữ tập lệnh tạo mẫu để kiểm tra các thuật toán, bạn có thể nhận thấy rằng tất cả các LIB cung cấp các phương thức nội suy hình ảnh nhanh (để lấy mẫu phụ hoặc mẫu quá mức) hoạt động trong 8 bit không dấu ( ________số 8). Điều này khá khó chịu nếu bạn đang làm việc với hình ảnh dấu phẩy động. PIL hỗ trợ phép nội suy điểm nổi, nhưng chỉ đối với một lớp, do đó quên đi RGB và scipy.misc.imresize không được chấp nhận và sớm bị loại bỏ. Hạn chế của uint8 là nó không thể lưu trữ các giá trị âm, điều này rất quan trọng nếu bạn đang thực hiện tách tần số theo kiểu sóng con. Tất nhiên, có những mánh khóe như thêm 127 và bình thường hóa, nhưng các thủ thuật nói chung là xấu, và khả năng số học điểm nổi của CPU hiện đại làm cho bất kỳ số nguyên số nguyên nào không xứng đáng với việc làm tròn. Hãy để sạch sẽ từ mặt đất lên. Hạn chế khác mà mọi người thường quên, đang làm việc trong uint8 luôn cho rằng các pixel của bạn được mã hóa không tuyến tính bằng OETF (chức năng chuyển điện tử), được gọi là gamma không đúng Do đó, đèn thấp hơn), tạo ra dải trong độ dốc mịn trong đèn thấp. Nhưng việc thực hiện các chập, do đó nội suy và bản đồ tuyến tính, trên hình ảnh được mã hóa OETF không giữ được tính nhất quán vật lý của rác pixel với phát xạ ánh sáng cảnh và sẽ làm rối độ dốc, có thể tạo ra các tác phẩm cạnh:

Bạn thấy ở đây rằng hình ảnh được xoay mà không cần tiết kiệm). Điều này sẽ không hiển thị trong mỗi hình ảnh bạn sẽ xử lý, nhưng nó không phải vì bạn không thấy điều đó xảy ra. Vì vậy, một lần nữa, theo tinh thần làm việc sạch sẽ, hãy để Lôi làm việc với OETF. Trong đó ngụ ý làm việc trong

import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out
1 vì uint8 mà không có OETF sẽ thất bại. Vì vậy, chúng tôi cần một cách tốt (và nhanh) để nội suy hình ảnh
import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out
1 RGB. Trong số tất cả các phương pháp nội suy, song song là hiệu quả nhất của OK-ish. Nó đã giành chiến thắng cung cấp cho bạn độ chính xác của Lanczos 3, nhưng nó rất tốt cho thao tác hình ảnh cấp thấp như các bộ lọc có hướng dẫn và như vậy.

#Tuyệt quá ! Bây giờ, mã xin vui lòng

Được rồi, được rồi, đây là Python:

import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out

Và đây là C Pure C với OpenMP pragmas để vectorize, paralellize và như vậy:

static inline void interpolate_bilinear(const float *const restrict in, const size_t width_in, const size_t height_in,
                                        float *const restrict out, const size_t width_out, const size_t height_out,
                                        const size_t ch)
{
#ifdef _OPENMP
#pragma omp parallel for simd collapse(2) default(none) \
  schedule(simd:static) aligned(in, out:64) \
  firstprivate(in, out, width_out, height_out, width_in, height_in, ch)
#endif
  for(size_t i = 0; i < height_out; i++)
    for(size_t j = 0; j < width_out; j++)
    {
      // Relative coordinates of the pixel in output space
      const float x_out = (float)j /(float)width_out;
      const float y_out = (float)i /(float)height_out;

      // Corresponding absolute coordinates of the pixel in input space
      const float x_in = x_out * (float)width_in;
      const float y_in = y_out * (float)height_in;

      // Nearest neighbours coordinates in input space
      size_t x_prev = (size_t)floorf(x_in);
      size_t x_next = x_prev + 1;
      size_t y_prev = (size_t)floorf(y_in);
      size_t y_next = y_prev + 1;

      // Sanitize bounds - no need to check for < 0
      x_prev = (x_prev < width_in) ? x_prev : width_in - 1;
      x_next = (x_next < width_in) ? x_next : width_in - 1;
      y_prev = (y_prev < height_in) ? y_prev : height_in - 1;
      y_next = (y_next < height_in) ? y_next : height_in - 1;

      // Memory addresses of neighbouring pixels in input buffer
      const size_t Y_prev = y_prev * width_in;
      const size_t Y_next =  y_next * width_in;
      const float *const Q_NW = (float *)in + (Y_prev + x_prev) * ch;
      const float *const Q_NE = (float *)in + (Y_prev + x_next) * ch;
      const float *const Q_SE = (float *)in + (Y_next + x_next) * ch;
      const float *const Q_SW = (float *)in + (Y_next + x_prev) * ch;

      // Distances between neighbour nodes in input space
      const float Dy_next = (float)y_next - y_in;
      const float Dy_prev = 1.f - Dy_next; // because next - prev = 1
      const float Dx_next = (float)x_next - x_in;
      const float Dx_prev = 1.f - Dx_next; // because next - prev = 1

      // Interpolate over ch layers
      float *const pixel_out = (float *)out + (i * width_out + j) * ch;

      #pragma unroll
      for(size_t c = 0; c < ch; c++)
      {
        pixel_out[c] = Dy_prev * (Q_SW[c] * Dx_next + Q_SE[c] * Dx_prev) +
                       Dy_next * (Q_NW[c] * Dx_next + Q_NE[c] * Dx_prev);
      }
    }
}

Lưu ý rằng C lấy số lượng kênh làm tham số, bởi vì hàm được ghi lại sau đó, trong khi Python đặt 3 kênh. Hãy chắc chắn biên dịch mã C với ____14 để có hiệu suất tốt và sử dụng bộ đệm hình ảnh đầu vào và đầu ra được căn chỉnh trên các địa chỉ 64 bit để vector hóa trên các nền tảng AVX2 hoạt động.

#Looping trên pixel trong Python, thực sự?

Chúng tôi chưa hoàn thành. Hãy để khởi chạy mã đó và nội suy hình ảnh 4872 × 3233 × 3 thành 1218 × 808 × 3 (tỷ lệ xuống 16):

from PIL import Image

# load image
im = Image.open("../img/153412.jpg")
width_2 = im.width // 4
height_2 = im.height // 4

# Go to normalized float and undo gamma
# Note : sRGB gamma is not a pure power TF, but that will do
im2 = (np.array(im) / 255.)**2.4

# Interpolate in float64
out = np.zeros((height_2, width_2, 3))
out = interpolate_bilinear(im2, im.width, im.height, out, width_2, height_2)

# Redo gamma and save back in uint8
out = (out**(1/2.4) * 255.).astype(np.uint8)
Image.fromarray(out)
34.7 s ± 812 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

O.U.T.C.H. Life is too short for unoptimised code. This is the reason why you want to use Python libs only as an API of wrappers for not-so-nice-looking loop operations written in C and compiled. What Numpy actually is. But C is another low-level flavor of high-level headache and you don’t want to deal with that when prototyping. So you want to have nice-looking Python code at C speed ? There is this awesome project, Numba, that compiles just-in-time Python to machine code through LLVM and is meant to work with Numpy. Here, since our loop is almost pure C (no fancy pythonic features), there is very little to change. If you ever used Cython, you know that it’s all the burden of pure C with all the burden of Python, and not the full performance of C. It’s actually faster to simply write and compile the C function above and wrap it in a Python module. Cython seems like a good intent started without clearly writing down the specifications before starting to fiddle. It’s mtessy and aweful to use. But thanks to Numba awesomness, we will only need to replace the

import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out
5function that produces the iterable object by
import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out
6, which allows a parallel loop unrolling, then add a
import numpy as np
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in range(height_out):
        for j in range(width_out):
            # Relative coordinates of the pixel in output space
            x_out = j / width_out
            y_out = i / height_out

            # Corresponding absolute coordinates of the pixel in input space
            x_in = (x_out * width_in)
            y_in = (y_out * height_in)

            # Nearest neighbours coordinates in input space
            x_prev = int(np.floor(x_in))
            x_next = x_prev + 1
            y_prev = int(np.floor(y_in))
            y_next = y_prev + 1

            # Sanitize bounds - no need to check for < 0
            x_prev = min(x_prev, width_in - 1)
            x_next = min(x_next, width_in - 1)
            y_prev = min(y_prev, height_in - 1)
            y_next = min(y_next, height_in - 1)
            
            # Distances between neighbour nodes in input space
            Dy_next = y_next - y_in;
            Dy_prev = 1. - Dy_next; # because next - prev = 1
            Dx_next = x_next - x_in;
            Dx_prev = 1. - Dx_next; # because next - prev = 1
            
            # Interpolate over 3 RGB layers
            for c in range(3):
                array_out[i][j][c] = Dy_prev * (array_in[y_next][x_prev][c] * Dx_next + array_in[y_next][x_next][c] * Dx_prev) \
                + Dy_next * (array_in[y_prev][x_prev][c] * Dx_next + array_in[y_prev][x_next][c] * Dx_prev)
                
    return array_out
7 decorator before the function declaration :

from numba import jit, prange

@jit(nopython=True, fastmath=True, nogil=True, cache=True, parallel=True)
def interpolate_bilinear(array_in, width_in, height_in, array_out, width_out, height_out):
    for i in prange(height_out):
        for j in prange(width_out):
            ...

Tôi cho phép bạn google các args, nhưng về cơ bản chúng tôi tắt mọi điều Python (khóa phiên dịch toàn cầu, đáng chú ý, ngăn chặn thực thi đa xử lý thực sự trong Python), và bật song song hóa, vector hóa và lặp lại vòng lặp. Lần đầu tiên bạn gọi chức năng, nó sẽ được biên dịch cho các loại đầu vào bạn sử dụng. Và sau đó, tiếp theo:

6.81 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Bây giờ, nếu thay vì 64 bit phao (mặc định của Numpy), bạn sẽ cung cấp cho nó 32 bit (vẫn còn quá đủ):

3.81 ms ± 231 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Tất nhiên, việc biên dịch mất một thời gian, nhưng mã được biên dịch được lưu trữ, vì vậy nếu bạn gọi hàm nhiều lần, nó sẽ chỉ được tính toán một lần. Trong trường hợp này, cần có thêm 2 ms để biên dịch, trên đầu các hình trên. Nó vẫn nhanh hơn 9121 lần trên Intel® Xeon® CPU E3-1505M V6 @ 3,00 GHz × 8, khá tuyệt vời cho một dòng trang trí đơn giản, phải không? Lưu ý hơn Numba có thể chuẩn bị chức năng đó thành hạt nhân CUDA để giảm tải nó vào GPU NVIDIA của bạn với công việc bổ sung từ bạn. Tuy nhiên, hãy nhớ hơn là sao chép bộ đệm hình ảnh từ RAM (máy chủ) sang VRAM (thiết bị GPU) khá đắt và, đối với hoạt động nhẹ này, chi phí này có lẽ không đáng. Bạn sẽ phải xếp một số bộ lọc như thế (và đảm bảo hình ảnh được sao chép ngay từ đầu và ở cuối đường ống) để làm cho máy tính GPU có giá trị Trở tròn bộ nhớ. Ngoài ra, lưu ý rằng nó được biên dịch cho kiến ​​trúc CPU cụ thể hiện tại của bạn, vì vậy mã được tối ưu hóa tốt cho máy của bạn, nhưng không nhất thiết phải di động. Nếu bạn muốn biên dịch trước thời gian, để phân phối các bit được biên dịch trong mô-đun Python, thì nó cũng có thể thực hiện được, nhưng cần thêm các bước.

#Cái gì về việc loại bỏ gamma?

Bây giờ, bạn có thể tự hỏi nó tạo ra sự khác biệt gì để nội suy có hoặc không có gamma/oetf. Hãy xem nào :

Ở kích thước này, và đối với loại hình ảnh mơ hồ này, nó không tạo ra sự khác biệt đáng chú ý. Nhưng, nếu chúng ta tính toán sự khác biệt giữa cả hai phương pháp và tăng cường nó, nó sẽ trở nên rõ ràng:

Hướng dẫn bilinear interpolation image processing python - python xử lý hình ảnh nội suy song tuyến
Sự khác biệt nâng cao giữa cả hai phương pháp Mặt nạ khác biệt này cho thấy rõ rằng chúng ta có sự khác biệt xung quanh các cạnh, đặc biệt là các phương pháp tương phản và ngay cả ở giữa các khu vực sáng. Vì vậy, hãy cẩn thận hơn bởi vì nó có thể nổ tung vào mặt bạn, và trong trường hợp nghi ngờ, luôn luôn tự hỏi mình: Những phát thải nhẹ sẽ làm gì? Tôn trọng vận chuyển ánh sáng luôn là điều cần thiết để có được kết quả trông tự nhiên, bởi vì ánh sáng là sự thật trực quan của chúng ta, và nó chắc chắn không được mã hóa gamma. Đặc biệt ở đây, làm việc với một phép nội suy tuyến tính và chỉ theo hướng chính của 4 đỉnh nội suy, chúng ta không thể giải thích cho những thay đổi trong độ cong độ dốc mà gamma sẽ đưa ra (có thể không theo hướng chính).

#Suy nghĩ

Tôi đến từ tính toán khoa học trong kỹ thuật cơ học, với Matlab, Python, Simulink và các lượt thích. Không ai dạy tôi biên soạn/các ngôn ngữ cấp thấp hơn như C, và tôi đã nỗ lực rất nhiều để tránh việc học chúng và mất trí nhớ vào các con trỏ số học và bộ đệm bộ nhớ tìm kiếm độ trễ. Trong nhiều năm, tôi đã thử viết Python được tối ưu hóa và nhanh chóng dựa vào các lớp trừu tượng. Và tôi đã thất bại. Cho đến khi tôi cuối cùng đã phải học C, và libs như SSE2 Intrinsics và OpenCL, vì Darktable. Có các hoạt động pixel bị hack rộng rãi bằng cách sử dụng song song hóa và vector hóa, thông qua nội tại vector openMP và x86, với quyền truy cập trực tiếp vào bộ đệm bộ nhớ, bây giờ tôi hiểu rằng tôi hiểu rằng, để viết mã nhanh bằng python, bạn cần phải suy nghĩ bằng C và viết nó Tương tự như cách bạn muốn trong C, hoặc gọi các chức năng đúng cách đúng cách, biết những gì bạn muốn giảm tải cho thư viện C bên trong hoặc những gì bạn có thể làm ở cấp độ Pythonic. Mặc dù các dự án như Numba hoặc Cython, nhưng hiệu suất đầy hứa hẹn với C Pure C nhưng dễ viết như Python thuần túy rất tuyệt, cuối cùng, kỹ năng viết thực sự nhanh chóng cần một số (rất nhiều) sự hiểu biết cấp thấp. Và vì những người như tôi học lập trình theo cách dễ dàng của người Viking, với các ngôn ngữ được giải thích, họ sẽ không bao giờ có thể viết mã nhanh. Đó là một sự xấu hổ, bởi vì các ngôn ngữ kịch bản là tiêu chuẩn thực tế cho hầu hết các lớp ứng dụng và các lớp phía máy chủ. Vì vậy, cuối cùng, tôi sợ tất cả mọi người đang viết mã shitty được tối ưu hóa rất nhiều vì nó dễ dàng hơn và không ai có thời gian để tối ưu hóa cấp thấp trong thế giới kỹ thuật số có nhịp độ nhanh này. Điều đó sẽ ổn nếu kỹ thuật số không dựa vào điện để chạy. Tôi sợ rằng chúng ta đang lãng phí rất nhiều năng lượng quý giá với tất cả những điều đó, và mọi người tiếp tục mua CPU mạnh hơn chỉ để cho phép các nhà phát triển tiếp tục tối ưu hóa. Thế giới kỳ lạ. Hình ảnh ngựa lịch sự của một người nào đó trên Diễn đàn Darktable.fr. Xin lỗi, tôi quên mất ai.

Liên kết tải trang
Đi đến đầu

Nội suy song song trong xử lý hình ảnh là gì?

Trong tầm nhìn máy tính và xử lý hình ảnh, phép nội suy song tuyến được sử dụng để lấy mẫu lại hình ảnh và kết cấu. Một thuật toán được sử dụng để ánh xạ vị trí pixel màn hình đến một điểm tương ứng trên bản đồ kết cấu. Trung bình có trọng số của các thuộc tính (màu sắc, độ trong suốt, v.v.)used to resample images and textures. An algorithm is used to map a screen pixel location to a corresponding point on the texture map. A weighted average of the attributes (color, transparency, etc.)

Làm cách nào để sử dụng phép nội suy song phương trong Python?

Từ nhập khẩu scipy nội suy ..
Nhập Numpy dưới dạng NP ..
Nhập matplotlib.pyplot như plt ..
x = np.Arange (-10,01, 10,01, 0,50).
y = np.Arange (-10,01, 10,01, 0,50).
xx, yy = np.Meshgrid (x, y).
z = np.cos (xx ** 2+yy ** 2).
f = nội suy.interp2d (x, y, z, kint = 'Quintic').

Nội suy hình ảnh trong Python là gì?

Đưa ra một lựa chọn được lấy mẫu ngẫu nhiên của các pixel từ một hình ảnh, scipy.interpolate.griddata có thể được sử dụng để nội suy trở lại biểu diễn của hình ảnh gốc.Mã bên dưới thực hiện điều này, khi được cho ăn tên của một tệp hình ảnh trên dòng lệnh. interpolate. griddata could be used to interpolate back to a representation of the original image. The code below does this, when fed the name of an image file on the command line.

Sự khác biệt giữa nội suy song song và bicubic là gì?

Trái ngược với phép nội suy song tuyến, chỉ đưa 4 pixel (2 × 2) vào tài khoản, nội suy bicubic xem xét 16 pixel (4 × 4).Hình ảnh được ghép lại bằng phép nội suy bicubic có thể có các tạo tác nội suy khác nhau, tùy thuộc vào giá trị B và C được chọn.. Images resampled with bicubic interpolation can have different interpolation artifacts, depending on the b and c values chosen.