C++绘棋盘格,并调整图片dpi,Python 绘棋盘格

617 阅读1分钟

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%尺寸
5b5912dbf168d5a2a6e96fcfa13e1ff.png

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()

Ma对象的 dot()mul() ,点乘,向量乘相关:blog.csdn.net/dcrmg/artic…