- 抄袭自(7条消息) 制作棋盘格标定板(固定分辨率解决尺度问题)_道法自然-CSDN博客_棋盘格标定板
(7条消息) python opencv 画黑白棋盘_feixin620的博客-CSDN博客_python绘制黑白棋盘
C++ 绘棋盘格,修改dpi
(这招只适用于jpg
图片)
// make_chessboard.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <fcntl.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
template<typename T>
uint64_t getFileSize(T& fs)
{
uint64_t cur_index = fs.tellg();
fs.seekg(0, std::ios::end);
uint64_t file_size = fs.tellg();
fs.seekg(cur_index, std::ios::beg);
return file_size;
}
// method from https://blog.csdn.net/shirly_xr/article/details/83792028
bool SetResolution(const char* path, int iResolution) {
// 获取文件大小
int len = 0;
{
std::ifstream fs(path, std::ios::ate | std::ios::in | std::ios::binary);
len = getFileSize(fs);
}
FILE* file = fopen(path, "rb+"); // - 打开图片文件
if (!file) return false;
// int len = ftell(file);
std::cout << "len: " << len << std::endl;
char* buf = new char[len];
fread(buf, sizeof(char), len, file); // - 将图片数据读入缓存
char* pResolution =
(char*)&iResolution; // - iResolution为要设置的分辨率的数值,如72dpi
buf[0x0D] = 1; // - 设置使用图片密度单位
// - 水平密度,水平分辨率
buf[0x0E] = pResolution[1];
buf[0x0F] = pResolution[0];
// - 垂直密度,垂直分辨率
buf[0x10] = pResolution[1];
buf[0x11] = pResolution[0];
// - 将文件指针移动回到文件开头
fseek(file, 0, SEEK_SET);
// - 将数据写入文件,覆盖原始的数据,让修改生效
int ret = fwrite(buf, sizeof(char), len, file);
ret = fclose(file);
return true;
}
int main() {
//自定义标定板
int blockSize_mm = 30; // block边长,单位:mm
int blockNum = 9; // 行
int blockNum_col = 13; // 列
int resolution_ratio = 10;
// 格子 pix 边长,当图片的 dpi为254时,一个pix就是0.1mm
// int blockSize_pixel = blockSize_mm * resolution_ratio;
// 直接指定格子边长20mm
int blockSize_pixel = 200;
int edge_size_pixel = blockSize_pixel / 2;
int imageSize = blockSize_pixel * blockNum;
int imageSize_col = blockSize_pixel * blockNum_col;
Mat chessBoard = cv::Mat::zeros(imageSize, imageSize_col, CV_8UC1);
for (int i = 0; i < imageSize_col; i = i + blockSize_pixel) { // 列
for (int j = 0; j < imageSize; j = j + blockSize_pixel) {
Mat ROI = chessBoard(Rect(i, j, blockSize_pixel, blockSize_pixel));
if (((i + j) / blockSize_pixel) % 2 == 0)
ROI.setTo(Scalar::all(0));
else
ROI.setTo(Scalar::all(255));
}
}
Mat chessBoard_final =
cv::Mat::zeros((imageSize + blockSize_pixel),
(imageSize_col + blockSize_pixel), CV_8UC1);
chessBoard_final.setTo(Scalar::all(255));
Rect chessBoard_rect =
Rect(edge_size_pixel, edge_size_pixel, imageSize_col, imageSize);
cout << "chessBoard_final.size() = " << chessBoard_final.size() << endl;
// chessBoard_final(chessBoard_rect) = chessBoard;
const std::string chess_broad_name = "chess_board.jpg";
chessBoard.copyTo(chessBoard_final(chessBoard_rect));
imshow("Chess board", chessBoard);
imwrite(chess_broad_name, chessBoard);
waitKey(2000);
// 只能是jpg,才能修改dpi
// 图像分辨率实际的打印分辨率
int iResolution = 254;
SetResolution(std::string("./"+ chess_broad_name).c_str() , iResolution);
return 0;
}
注意,至关重要的一点:打印的时候按-->调整到100%尺寸
python
import cv2 as cv
import numpy as np
width = 11
height = 9
qipan_cell = 100
width_pix = (width + 1) * qipan_cell + qipan_cell # add extra qipan_cell for reserve blank
height_pix = (height + 1) * qipan_cell + qipan_cell
# white = (255,255,255)
# black = (0,0,0)
image = np.zeros((height_pix, width_pix, 3), dtype=np.uint8)
image.fill(255)
# 创建显示窗口
win_name = "qipan"
cv.namedWindow("qipan", cv.WINDOW_AUTOSIZE)
cv.imshow(win_name, image)
color = (255, 255, 255)
y0 = 0
fill_color = 0
for j in range(0, height + 1):
y = j * qipan_cell
for i in range(0, width + 1):
# rint(i)
x0 = i * qipan_cell
y0 = y
rect_start = (x0, y0)
x1 = x0 + qipan_cell
y1 = y0 + qipan_cell
rect_end = (x1, y1)
print(x0, y0, x1, y1, fill_color)
cv.rectangle(image, rect_start, rect_end, color, 1, 0)
# print(fill_color)
image[y0:y1, x0:x1] = fill_color
if width % 2:
if i != width:
fill_color = (0 if (fill_color == 255) else 255)
else:
if i != width + 1:
fill_color = (0 if (fill_color == 255) else 255)
# image[0:20,0:20] = 0
# image[40:60,0:20] = 0
cv.imwrite("qipan_%d_W_%d_H.png" % (width, height), image)
# cv.imshow(win_name, image)
# cv.waitKey()