import math
import os
import numpy as np
import cv2
from colour_demosaicing import demosaicing_CFA_Bayer_bilinear
from matplotlib import pyplot as plt
def black_sub(filename, height=800, width=800):
raw_image = np.fromfile(filename, dtype=np.uint16)
print(len(raw_image))
raw_image = raw_image.reshape([height, width])
# raw_image =raw_image>>6
print('raw20x20 :\n', raw_image[20:30, 20:30])
# black level
black_level = 16
white_level = 1023
normalized_image = raw_image.astype(np.float32) - black_level
# if some values were smaller than black level
normalized_image[normalized_image < 0] = 0
normalized_image = normalized_image / (white_level - black_level)
print(normalized_image.min(), normalized_image.max())
# plt.figure()
# plt.imshow(normalized_image, cmap='gray')
# plt.show()
# demosciac
# rgb = demosaicing_CFA_Bayer_Menon2007(normalized_image, "BGGR")
rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "RGGB")
rgb_save = rgb * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw.png', rgb_save[..., ::-1])
return normalized_image
def bilinear_interp2(data, new_h, new_w):
"""
与opencv的resize bilinear 函数一致
:param data:
:param new_h:
:param new_w:
:return:
"""
h, w = data.shape
out = np.zeros((new_h, new_w), dtype=np.float32)
for i in range(new_h):
for j in range(new_w):
hv = (i+0.5)*h/new_h-0.5
wv = (j+0.5)*w/new_w-0.5
hh = math.floor(hv)
ww = math.floor(wv)
u = hv-hh
v = wv-ww
if hh < 0:
hh = 0
u = 0
if hh >= h - 1:
hh = h - 2
u = 1.0
if ww < 0:
ww = 0
v = 0
if ww >= w - 1:
ww = w - 2
v = 1.0
#print(hh, ww)
out[i, j] = (1-u)*(1-v)*data[hh, ww]+u*(1-v)*data[hh+1, ww]+(1-u)*v*data[hh, ww+1]+u*v*data[hh+1, ww+1]
return out
def bilinear_interp1(data, new_h, new_w):
h, w = data.shape
out = np.zeros((new_h, new_w), dtype=np.float32)
# u_save = []
for i in range(new_h):
for j in range(new_w):
hv = (i+0.5)*(h-1)/(new_h-1)-0.5
wv = (j+0.5)*(w-1)/(new_w-1)-0.5
hh = math.floor(hv)
ww = math.floor(wv)
u = hv-hh
v = wv-ww
#print(hh, ww)
# u_save.append(u)
out[i, j] = (1-u)*(1-v)*data[hh, ww]+u*(1-v)*data[hh+1, ww]+(1-u)*v*data[hh, ww+1]+u*v*data[hh+1, ww+1]
# u_save = np.array(u_save)
# np.savetxt('u1.txt', u_save.reshape([new_h, new_w]))
return out
def bilinear_interp(data, new_h, new_w):
"""
:param data: origin data
:param new_h: the height of dst
:param new_w: the width of dst
:return:
"""
h, w = data.shape # the height and width of origin data
y = np.arange(new_h)
x = np.arange(new_w)
jj, ii = np.meshgrid(x, y)
hv = (ii + 0.5) * (h - 1) / (new_h - 1) - 0.5
wv = (jj + 0.5) * (w - 1) / (new_w - 1) - 0.5
hh = np.floor(hv).astype(np.int32)
ww = np.floor(wv).astype(np.int32)
u = hv - hh
v = wv - ww
# np.savetxt('u0.txt', u.reshape([new_h, new_w]))
# data = data.reshape(-1)
# hh = hh.reshape(-1).astype(np.int)
# ww = hh.reshape(-1).astype(np.int)
# u = u.reshape(-1)
# v = v.reshape(-1)
w00 = (1-u)*(1-v)
w01 = u * (1-v)
w10 = (1-u) * v
w11 = u*v
out = w00 * data[hh, ww] + w10 * data[hh, ww + 1] + w01 * data[(hh + 1) ,ww] + w11 * data[hh + 1 , ww + 1]
# out= (1 - u) * (1 - v) * data[hh, ww] + u * (1 - v) * data[hh + 1, ww] + (1 - u) * v * data[
# hh, ww + 1] + u * v * data[hh + 1, ww + 1]
return out.reshape([new_h, new_w])
def bilinear_interp3(data, new_h, new_w):
"""
:param data: origin data
:param new_h: the height of dst
:param new_w: the width of dst
:return:
"""
h, w = data.shape # the height and width of origin data
y = np.arange(new_h)
x = np.arange(new_w)
jj, ii = np.meshgrid(x, y)
hv = (ii + 0.5) * h/new_h - 0.5
wv = (jj + 0.5) * w/new_w - 0.5
hh = np.floor(hv).astype(np.int32)
ww = np.floor(wv).astype(np.int32)
u = hv - hh
v = wv - ww
u[hh < 0] = 0
hh[hh < 0] = 0
u[hh >= h - 1] = 1.0
hh[hh >= h - 1] = h - 2
v[ww < 0] = 0
ww[ww < 0] = 0
v[ww >= w - 1] = 1.0
ww[ww >= w - 1] = w - 2
# np.savetxt('u0.txt', u.reshape([new_h, new_w]))
# data = data.reshape(-1)
# hh = hh.reshape(-1).astype(np.int)
# ww = hh.reshape(-1).astype(np.int)
# u = u.reshape(-1)
# v = v.reshape(-1)
w00 = (1-u)*(1-v)
w01 = u * (1-v)
w10 = (1-u) * v
w11 = u*v
out = w00 * data[hh, ww] + w10 * data[hh, ww + 1] + w01 * data[(hh + 1) ,ww] + w11 * data[hh + 1 , ww + 1]
# fpga中可以通过查找表来实现
# 在初始尺寸以及目标尺寸确定之后(h,w,new_h,new_w), w00,w01,w10,w11这四个变量对于任何图像都是一致的和确定的。
# hh, ww对于任何图像也是一致的和确定的
# 因此首先保存下来,然后通过查找来实现
return out.reshape([new_h, new_w])
if __name__ == "__main__":
interpolation = 'bilinear' # cubic, area, nearest
table_h = 40
table_w = 40
if interpolation == 'bilinear':
inter = cv2.INTER_LINEAR
elif interpolation == 'nearest':
inter = cv2.INTER_NEAREST
elif interpolation == 'cubic':
inter = cv2.INTER_CUBIC
elif interpolation == 'area':
inter = cv2.INTER_AREA
else:
print('error input !')
height = 800
width = 800
new_h = 400
new_w = 400
dir = r'D:\code\interp\image'
files = os.listdir(dir)
for file in files:
if file.endswith('.raw'):
filename = os.path.join(dir, file)
normalized_image = black_sub(filename)
run_pipe_shading = 1
if run_pipe_shading:
# shading
# r_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_r.txt', dtype=np.float32)
# g_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_g.txt', dtype=np.float32)
# b_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_b.txt', dtype=np.float32)
r_gain = np.loadtxt(r'D:\code\interp\gains_mean_r.txt', dtype=np.float32)
g_gain = np.loadtxt(r'D:\code\interp\gains_mean_g.txt', dtype=np.float32)
b_gain = np.loadtxt(r'D:\code\interp\gains_mean_b.txt', dtype=np.float32)
# valid_table
r_gain = cv2.resize(r_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
g_gain = cv2.resize(g_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
b_gain = cv2.resize(b_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
np.savetxt(r'D:\code\interp\gains_mean_r' + interpolation + str(table_w) + '.txt', r_gain, fmt='%.7f')
np.savetxt(r'D:\code\interp\gains_mean_g' + interpolation + str(table_w) + '.txt', g_gain, fmt='%.7f')
np.savetxt(r'D:\code\interp\gains_mean_b' + interpolation + str(table_w) + '.txt', b_gain, fmt='%.7f')
# r_gain = cv2.resize(r_gain, (height // 2, width // 2), interpolation=inter)
# g_gain = cv2.resize(g_gain, (height // 2, width // 2), interpolation=inter)
# b_gain = cv2.resize(b_gain, (height // 2, width // 2), interpolation=inter)
r_gain = bilinear_interp3(r_gain, new_h, new_w)
g_gain = bilinear_interp3(g_gain, new_h, new_w)
b_gain = bilinear_interp3(b_gain, new_h, new_w)
normalized_image[0::2, 0::2] *= r_gain
normalized_image[1::2, 1::2] *= g_gain
normalized_image[0::2, 1::2] *= g_gain
normalized_image[1::2, 0::2] *= b_gain
rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "RGGB")
# brigtness_aline = 1
# if brigtness_aline:
# rgb *= 2.7
rgb_save = rgb * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + 'z3_raw_shading_' + interpolation + str(table_w) + '.png',
rgb_save[..., ::-1])
- c++版本code , 和opencv resize基本一致,因为有数据转换,所以有精度损失
https://blog.csdn.net/hddryjv/article/details/83791042?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83791042-blog-106761993.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83791042-blog-106761993.pc_relevant_default&utm_relevant_index=2
OpenCV中resize函数五种插值算法的实现过程
#include
#include
using namespace cv;
//typedef unsigned char uchar;
int bilinear_interp(Mat matSrc, Mat matDst1, Mat matDst2, float scale_x, float scale_y) {
uchar* dataDst = matDst1.data;
int stepDst = matDst1.step;
uchar* dataSrc = matSrc.data;
int stepSrc = matSrc.step;
int iWidthSrc = matSrc.cols;
int iHiehgtSrc = matSrc.rows;
for (int j = 0; j < matDst1.rows; ++j)
{
float fy = (float)((j + 0.5) * scale_y - 0.5);
int sy = cvFloor(fy);
fy -= sy;
//sy = std::min(sy, iHiehgtSrc - 2);
//sy = std::max(0, sy);
if (sy < 0)
{
fy = 0, sy = 0;
}
if (sy >= iHiehgtSrc - 1)
{
fy = 1.0, sy = iHiehgtSrc - 2;
}
short cbufy[2];
cbufy[0] = cv::saturate_cast((1.f - fy) * 2048);
cbufy[1] = 2048 - cbufy[0];
for (int i = 0; i < matDst1.cols; ++i)
{
float fx = (float)((i + 0.5) * scale_x - 0.5);
int sx = cvFloor(fx);
fx -= sx;
if (sx < 0)
{
fx = 0, sx = 0;
}
if (sx >= iWidthSrc - 1)
{
fx = 1.0, sx = iWidthSrc - 2;
}
short cbufx[2];
cbufx[0] = cv::saturate_cast((1.f - fx) * 2048);
cbufx[1] = 2048 - cbufx[0];
for (int k = 0; k < matSrc.channels(); ++k)
{
*(dataDst + j * stepDst + 3 * i + k) = (*(dataSrc + sy * stepSrc + 3 * sx + k) * cbufx[0] * cbufy[0] +
*(dataSrc + (sy + 1) * stepSrc + 3 * sx + k) * cbufx[0] * cbufy[1] +
*(dataSrc + sy * stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[0] +
*(dataSrc + (sy + 1) * stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[1]) >> 22;
}
}
}
cv::imwrite("linear_12.jpg", matDst1);
cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1);
cv::imwrite("linear_2.jpg", matDst2);
return 1;
}
int main()
{
std::cout << "Hello World!\n";
Mat img; //
img = imread("D:\\dataset\\\ccm\\2022-06-21-15-08-20_raw_gamma3.png");
int width = img.cols;
int height = img.rows;
if (img.empty()) // 判断是否导入图片
{
std::cout << "请确认图片正确位置!" << std::endl;
return -1; // 返回-1
}
namedWindow("test", WINDOW_NORMAL); // 创建一个常规窗口
imshow("test", img); // 展示图片
waitKey(0); // 获取键盘按键响应
int dstHeight = height * 2;
int dstWidth = width * 2;
Mat img2(dstHeight, dstWidth, CV_8UC3), img3(dstHeight, dstWidth, CV_8UC3);
float scale_x = 0.5;
float scale_y = 0.5;
bilinear_interp(img, img2, img3, scale_x, scale_y);
}