编程水平测试

在已有代码的基础上实现图片的各种效果,我就写个思路

读取

老师写了,不用管

合成

参考合成

拆解

可能就是控制rgb三色单通道的关闭

作业中的调色

在ImageMain.cpp的基础上完成下列任务:
(1)将buf中的图像数据按通道存入三个二维数组,分别为b、g、r(蓝绿红)。
(2)调色:按比例调整bgr的值,以产生不同的颜色效果。
bmp图片的宽度(w)应该为4的倍数,才可以正常处理

头文件

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<Windows.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;

定义数组

// 存储图片的二维数组
#define MAX_H 3000
#define MAX_W 3000
char r[MAX_H][MAX_W];
char g[MAX_H][MAX_W];
char b[MAX_H][MAX_W];

然后调色,按比例调整rgb的值,以产生不同的颜色效果。

void Process(char* buf, DWORD& w, DWORD& h, const int b_weight, const int g_weight, const int r_weight)
{
	char* p;
	double b_w, g_w, r_w;
	// Robust
	if (!b_weight || !g_weight || !r_weight) {
		cout << "error\n";
		return;
	}
	// 计算比例:
	b_w = (double)b_weight / (b_weight + g_weight + r_weight);
	g_w = (double)g_weight / (b_weight + g_weight + r_weight);
	r_w = (double)r_weight / (b_weight + g_weight + r_weight);

	p = buf;
	//int r, g, b;
	for (int j = 0; j < h; j++)
	{
		for (int i = 0; i < w; i++)
		{
			if ((int)*p * b_w > 255)*p = 255;   //越界问题,下面两个同理,就不写了
			else*p = *p * b_w;
			p++;
			b[j][i] = *p;
			*p = *p * g_w; p++;
			g[j][i] = *p;
			*p = *p * r_w; p++;
			r[j][i] = *p;
		}
	}
}

然后在main文件里加

int b_weight = 1, g_weight = 2, r_weight = 3;

加边框

有两种方法:

  • BORDER_CONSTANT:用恒定值(即255或0)填充图像
  • BORDER_REPLICATE:原始边缘的行或列复制到额外边框

或者更简单一点:将图像最外面一层改掉

void process1(int w,int h){
   for(i=0;i<w;++i){
       r[i][0]=0;//下面gb通道同理
       r[i][h]=0;
   }
   for(j=0;j<h;++j){
       r[0][j]=0;
       r[w][j]=0;
   }
}
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
//声明变量
Mat src, dst;
int top, bottom, left, right;
int borderType;
const char* window_name = "copyMakeBorder Demo";
RNG rng(12345);

int main( int, char** argv )
{
 int c;
 //加载源图像src
 src = imread( argv[1] );
 if( src.empty() )
  {
   printf(" No data entered, please enter the path to an image file \n");
   return -1;
  }
    
 printf( "\n \t copyMakeBorder Demo: \n" );
 printf( "\t -------------------- \n" );
 printf( " ** Press 'c' to set the border to a random constant value \n");
 printf( " ** Press 'r' to set the border to be replicated \n");
 printf( " ** Press 'ESC' to exit the program \n");
 namedWindow( window_name, WINDOW_AUTOSIZE );//创建一个窗口
 //初始化定义边框大小(顶部,底部,左侧和右侧)的参数。值是src大小的5%
 top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
 left = (int) (0.05*src.cols); right = (int) (0.05*src.cols);
 dst = src;
 imshow( window_name, dst );
    
 //开始循环,如果按下'c'或'r',则borderType变量分别取值BORDER_CONSTANT或BORDER_REPLICATE
 for(;;)
    {
     c = waitKey(500);
     if( (char)c == 27 )
      { break; }
     else if( (char)c == 'c' )
      { borderType = BORDER_CONSTANT; }
     else if( (char)c == 'r' )
      { borderType = BORDER_REPLICATE; }
     
     //在每次迭代中(0.5秒后),更新变量值
     Scalar value( rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255) );
     //调用函数cv :: copyMakeBorder来应用相应的填充
     copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );
     imshow( window_name, dst );
    }
 return 0;
}

src:源图像

dst:目标图像

top,bottom,left,right:图像两侧边框的长度(以像素为单位)。 将它们定义为图像原始大小的5%。

borderType:定义应用的边框类型。 对于此示例,它可以是常量或复制。

value:如果borderType为BORDER_CONSTANT,则这是用于填充边框像素的值。

反转

void process2(int h,int w) {
	for(int i =0;i<h;++i)
		for (int j =0 ; j < w; ++j) {
			swap(b[i][j], b[i][w - j]);
			swap(g[i][j], g[i][w - j]);
			swap(r[i][j], r[i][w - j]);
		}
}

应该是左右交换

旋转180度

void process3(int h,int w){
    for (int i=0;i<w;++i){
        for(int j=0;j<h-h/w*i;++j){
            swap(b[i][j],b[w-i][h-j]);
            swap(g[i][j],b[w-i][h-j]);
            swap(r[i][j],b[w-i][h-j]);
        }
    }
}

考完总结

合成就是简单的一张小图覆盖掉大图中的一部分,拆解就是从大图中拿出一部分图,都挺简单,完整程序就不放了