极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 8258|回复: 8

给女神画一张一笔肖像画!

[复制链接]
发表于 2016-10-3 03:00:06 | 显示全部楼层 |阅读模式
本帖最后由 草祭祀 于 2016-10-3 08:27 编辑

小草觊觎女神已久,一直想给女神送一份精致的创意礼物。
于是灵光一现,决定要做一张一笔肖像画!
待处理图片:
pp.jpg
先扔掉颜色信息黑白化:
black.jpg
  1. IplImage* origin0=cvLoadImage("pp.jpg",0);
  2. cvSaveImage("D:\\gray.jpg", origin0);
复制代码

直接载入一张黑白图片就可以了。
然后我们对图片进行摆动矩阵二值化:
bw.jpg
  1. double ratio=origin0->width>origin0->height?origin0->width/(double)(1<<(bits-2)):origin0->height/(double)(1<<(bits-2));
  2.         IplImage* origin=cvCreateImage(cvSize(origin0->width/ratio,origin0->height/ratio),8,1);
  3.         cvResize(origin0,origin);
  4.         IplImage* tempi=cvCloneImage(origin);
  5.         IplImage* tempi2=cvCloneImage(origin);
  6.         int c=3;
  7.         double gray=256/(double)(1<<(2*c));
  8.         for (int x=0;x<origin->width;x++)
  9.         {
  10.                 for (int y=0;y<origin->height;y++)
  11.                 {
  12.                         unsigned char g=origin->imageData[y*origin->widthStep+x];
  13.                         tempi->imageData[y*tempi->widthStep+x]=g/gray>ditherMatrix(x%(1<<(c-1)),y%(1<<(c-1)),c-1)?(char)(unsigned char)255:(char)(unsigned char)0;
  14.                 }
  15.         }
复制代码

什么叫做摆动矩阵呢,简单说就是一种打印时候用的二值化算法。一些打印机的颜色是由色点的密度组成的,白点越密,就看上去越亮,黑点越密,看上去越暗。
摆动矩阵代码:
  1. int dither[4]={0,2,3,1};
  2. int ditherMatrix(unsigned int x,unsigned int y,int c)
  3. {
  4.         if(c>0)
  5.                 return 4*ditherMatrix(x,y,c-1)+dither[(x>>(c))%2+(y>>(c))%2*2];
  6.         else
  7.                 return dither[(x>>(c))%2+(y>>(c))%2*2];
  8. }
复制代码

摆动矩阵使用的一种自相似的矩阵结构,要处理的图像每个像素的灰度如果大于摆动矩阵对应的值,则输出白点,如果小于则输出黑点。
一阶阵只有四个数字。
0 3
2 1
二阶阵有16个。
0 12 3 15
8 4 11 7
2 14 1 13
10 6 9 5
二阶阵是在一阶阵边长扩展一倍之后,四角的四方块加上一阶阵的四倍。
三阶阵就有64个了,以此类推。
  0  96  24 120   6 102  30 126
64  32  88  56  70  38  94  62
16 112   8 104  22 118  14 110
80  48  72  40  86  54  78  46
  4 100  28 124   2  98  26 122
68  36  92  60  66  34  90  58
20 116  12 108  18 114  10 106
84  52  76  44  82  50  74  42
三阶阵四角每4*4的块是由二阶阵加常数得到的的。
摆动矩阵尽可能利用黑和白两种颜色还原了图像的亮感和边缘,阶数小的时候,还原边缘比较锋利,阶数大的时候,还原亮感比较好。
一般取3阶或者4阶。

下面我要开始介绍希尔伯特曲线了。
希尔伯特曲线是一种分形曲线,可以一条线遍历一个空间。、
5b014d51g9412834048f4&amp;690.jpg
生成希尔伯特曲线:

  1. CvPoint2D32f hil[4]={cvPoint2D32f(-0.5,-0.5),cvPoint2D32f(-0.5,0.5),cvPoint2D32f(0.5,0.5),cvPoint2D32f(0.5,-0.5)};
  2. vector<CvPoint> vP;

  3. void hilbert(IplImage* img,CvPoint c,int order,int character,bool z)
  4. {
  5.         if(order==2)
  6.         {
  7.                 vP.push_back(cvPoint(c.x,c.y));
  8.         }
  9.         else
  10.         {
  11.                 if(order==4)
  12.                 {
  13.                         int x=c.x/order+img->width/2;
  14.                         int y=c.y/order+img->height/2;
  15.                         if(x>=0&&x<img->width&&y>=0&&y<img->height)
  16.                         {
  17.                                 if(img->imageData[(int)(y*img->widthStep+x)]==(char)(unsigned char)(z?255:0))
  18.                                 {
  19.                                         switch(character)
  20.                                         {
  21.                                         case 0:
  22.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  23.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,0,z);
  24.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,0,z);
  25.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  26.                                                 break;
  27.                                         case 1:
  28.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  29.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,1,z);
  30.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,1,z);
  31.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  32.                                                 break;
  33.                                         case 2:
  34.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  35.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,2,z);
  36.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,2,z);
  37.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  38.                                                 break;
  39.                                         case 3:
  40.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  41.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,3,z);
  42.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,3,z);
  43.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  44.                                                 break;
  45.                                         }
  46.                                 }
  47.                                 else
  48.                                 {
  49.                                         switch(character)
  50.                                         {
  51.                                         case 0:
  52.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  53.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  54.                                                 break;
  55.                                         case 1:
  56.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  57.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  58.                                                 break;
  59.                                         case 2:
  60.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  61.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  62.                                                 break;
  63.                                         case 3:
  64.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  65.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  66.                                                 break;
  67.                                         }
  68.                                 }
  69.                         }
  70.                         else
  71.                         {
  72.                                 switch(character)
  73.                                 {
  74.                                 case 0:
  75.                                         hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  76.                                         hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  77.                                         break;
  78.                                 case 1:
  79.                                         hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  80.                                         hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  81.                                         break;
  82.                                 case 2:
  83.                                         hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  84.                                         hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  85.                                         break;
  86.                                 case 3:
  87.                                         hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  88.                                         hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  89.                                         break;
  90.                                 }
  91.                         }
  92.                 }
  93.                 else
  94.                 {
  95.                         switch(character)
  96.                         {
  97.                         case 0:
  98.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  99.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,0,z);
  100.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,0,z);
  101.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  102.                                 break;
  103.                         case 1:
  104.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  105.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,1,z);
  106.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,1,z);
  107.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  108.                                 break;
  109.                         case 2:
  110.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  111.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,2,z);
  112.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,2,z);
  113.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  114.                                 break;
  115.                         case 3:
  116.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  117.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,3,z);
  118.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,3,z);
  119.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  120.                                 break;
  121.                         }
  122.                 }
  123.         }
  124. }
  125. IplImage* image2;
  126. void hilbertD(IplImage* ori,IplImage* image,int order)
  127. {
  128.         image2=cvCloneImage(image);
  129.         vP.clear();
  130.         hilbert(ori,cvPoint(0,0),order,0,0);
  131.         for (int i=0;i<vP.size()-1;i++)
  132.         {
  133.                 cvLine(image2,cvPoint(vP[i].x+image->width/2,vP[i].y+image->height/2),cvPoint(vP[i+1].x+image->width/2,vP[i+1].y+image->height/2),cvScalarAll(255),1);
  134.         }
  135.         cvSaveImage("reverse.jpg",image2);
  136.         cvZero(image);
  137.         vP.clear();
  138.         hilbert(ori,cvPoint(0,0),order,0,1);
  139.         for (int i=0;i<vP.size()-1;i++)
  140.         {
  141.                 cvLine(image,cvPoint(vP[i].x+image->width/2,vP[i].y+image->height/2),cvPoint(vP[i+1].x+image->width/2,vP[i+1].y+image->height/2),cvScalarAll(255),1);
  142.         }
  143. }
复制代码

这里我们把曲线改一下,对于白点,我们让曲线象元走三条边,对于黑点,让曲线只走一条边。
注意啦!
QQ图片20161003033216.png
请点开图片,并且用实际效果浏览!否则失真会相当严重。
最好离远点看,会很有效果。
于是得到效果:
hilbert.png
大功告成!
lesson.jpg
下面放个高清无码的...女神照...
h.jpg
hilbert.png

下面放送所有源码:
  1. // maze.cpp : 定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include "JHCap.h"
  5. #include "opencv/cv.h"
  6. #include "opencv/cxcore.h"
  7. #include "opencv/highgui.h"
  8. #include <math.h>
  9. #include <iostream>
  10. #include <vector>
  11. #include <random>
  12. #include <time.h>
  13. extern "C"{
  14. #include "kdtree.h"
  15. };
  16. #pragma comment(lib,"cv210.lib")
  17. #pragma comment(lib,"cxcore210.lib")
  18. #pragma comment(lib,"highgui210.lib")
  19. #pragma comment(lib,"JHCap2.lib")
  20. using namespace std;
  21. #include <stdio.h>
  22. #include <time.h>
  23. IplImage* img;
  24. int block=1;
  25. #define bits 10
  26. #define WIDTH (1<<(bits-1))
  27. #define HEIGHT (1<<(bits-1))

  28. enum {N=1,E=4,S=2,W=8};
  29. int DX[9];
  30. int DY[9];
  31. int OPPOSITE[9];
  32. int grid[WIDTH][HEIGHT];
  33. int shuffle_array(int *array, int size)
  34. {
  35.         int i;

  36.         for( i=0; i<(size - 1); i++) {
  37.                 int r = i + (rand() % (size - i));
  38.                 int temp = array[i];
  39.                 array[i] = array[r];
  40.                 array[r] = temp;
  41.         }
  42.         return 1;
  43. }
  44. bool check_valid(int x,int y, int grid[WIDTH][HEIGHT])
  45. {
  46.         if(x>=0&&x<WIDTH&&y>=0&&y<HEIGHT)
  47.                 return grid[x][y];
  48.         else
  49.                 return 1;
  50. }
  51. int carve_passage_from(int cx, int cy, int grid[WIDTH][HEIGHT])
  52. {

  53.         int dx, dy, nx, ny;
  54.         int directions[4] = {N, E, S, W};

  55.         //shuffle the direction array
  56.         shuffle_array(directions, 4);
  57.         int i;
  58.         /*
  59.         for(i = 0; i < 4; i++) {
  60.                 printf("Direction: %d\n", directions[i]);
  61.         }*/
  62.         //iterates through the direction then test if the cell in that direction is valid and
  63.         //within the bounds of the maze
  64.         for(i = 0; i < 4; i++) {
  65.                 dx = DX[directions[i]];
  66.                 dy = DY[directions[i]];
  67.         //        printf("Check direction=x:y - %d=%d:%d\n", directions[i], dx, dy);
  68.                 // check if the cell is valid
  69.                 nx = cx + dx;
  70.                 ny = cy + dy;
  71.                 // check if we are on valid grid
  72.                 if ( ((nx < WIDTH) & (nx >= 0)) & ((ny < HEIGHT) & (ny >= 0)) ) {
  73.                         //check if grid is not visited
  74.                         if (grid[nx][ny] == 0) {
  75.                                 grid[cx][cy] = (int)((int)grid[cx][cy] | (int)directions[i]);
  76.                                 grid[nx][ny] = (int)((int)grid[nx][ny] | (int)OPPOSITE[directions[i]]);
  77.                                 carve_passage_from(nx, ny, grid);
  78.                         }
  79.                 }

  80.         }
  81.         return 1;
  82. }
  83. void block_a(IplImage* image,int i, int j,bool b,CvScalar c=cvScalarAll(255))
  84. {
  85.         cvRectangle(image,cvPoint(i*block,j*block),cvPoint(i*block+block-1,j*block+block-1),cvScalar(b?c.val[0]:0,b?c.val[1]:0,b?c.val[2]:0),-1);
  86. }
  87. bool search4(IplImage* image,int cx,int cy,IplImage* temp)
  88. {
  89.         int xP=temp->width-cx,xM=cx,yP=temp->height-cy,yM=cy;
  90.         for (int x=cx;x<temp->width;x++)
  91.         {
  92.                 if(temp->imageData[cy*temp->widthStep+x]==(char)(unsigned char)255&&image->imageData[cy*image->widthStep+x]==(char)(unsigned char)0)
  93.                 {
  94.                         xP=x-cx;
  95.                         break;
  96.                 }
  97.         }
  98.         for (int x=cx;x>=0;x--)
  99.         {
  100.                 if(temp->imageData[cy*temp->widthStep+x]==(char)(unsigned char)255&&image->imageData[cy*image->widthStep+x]==(char)(unsigned char)0)
  101.                 {
  102.                         xM=cx-x;
  103.                         break;
  104.                 }
  105.         }
  106.         for (int y=cy;y<temp->height;y++)
  107.         {
  108.                 if(temp->imageData[y*temp->widthStep+cx]==(char)(unsigned char)255&&image->imageData[y*image->widthStep+cx]==(char)(unsigned char)0)
  109.                 {
  110.                         yP=y-cy;
  111.                         break;
  112.                 }
  113.         }
  114.         for (int y=cy;y>=0;y--)
  115.         {
  116.                 if(temp->imageData[y*temp->widthStep+cx]==(char)(unsigned char)255&&image->imageData[y*image->widthStep+cx]==(char)(unsigned char)0)
  117.                 {
  118.                         yM=cy-y;
  119.                         break;
  120.                 }
  121.         }
  122.         return xP%2&&xM%2&&yP%2&&yM%2;
  123. }
  124. bool mark_path(IplImage* image,int cx,int cy,int targetx,int targety,bool grid2[WIDTH*2+1][HEIGHT*2+1],bool temp[WIDTH*2+1][HEIGHT*2+1])
  125. {
  126.         int dx, dy, nx, ny;
  127.         int directions[4] = {N, E, S, W};
  128.         for(int i = 0; i < 4; i++) {
  129.                 dx = DX[directions[i]];
  130.                 dy = DY[directions[i]];
  131.                 nx = cx + dx;
  132.                 ny = cy + dy;
  133.                 if(temp[nx][ny]==0&&grid2[nx][ny]==1)
  134.                 {
  135.                         temp[nx][ny]=1;
  136.                         if(nx==targetx&&ny==targety)
  137.                         {
  138.                                 block_a(image,nx,ny,1,cvScalar(0,255,0));
  139.                                 return 1;
  140.                         }
  141.                         if(mark_path(image,nx,ny,targetx,targety,grid2,temp))
  142.                         {
  143.                                 block_a(image,nx,ny,1,cvScalar(0,255,0));
  144.                                 return 1;
  145.                         }
  146.                 }
  147.         }
  148.         return 0;
  149. }
  150. CvPoint main_role;
  151. void init()
  152. {
  153.         OPPOSITE[N] = S;
  154.         OPPOSITE[E] = W;
  155.         OPPOSITE[S] = N;
  156.         OPPOSITE[W] = E;

  157.         DX[N] = 0;
  158.         DX[E] = 1;
  159.         DX[S] = 0;
  160.         DX[W] = -1;

  161.         DY[N] = -1;
  162.         DY[E] = 0;
  163.         DY[S] = 1;
  164.         DY[W] = 0;
  165.         memset(&grid[0], 0, sizeof(grid));
  166. }
  167. IplImage* maze,*maze_origin;
  168. int generate(IplImage* image=0) {
  169.         int x,y;
  170.         /** Seed the random generator **/
  171.         srand((unsigned int)time((time_t *)NULL));


  172.         if(!image)
  173.                 carve_passage_from(0,0,grid);
  174.         /** Display the grid **/
  175.         /*
  176.         printf(" ");
  177.         for(x = 0; x < (WIDTH * 2); x++) {
  178.                 printf("_");
  179.         }
  180.         printf("\n");

  181.         for(y = 0; y < HEIGHT; y++) {
  182.                 printf("|");
  183.                 for(x = 0; x < WIDTH; x++) {
  184.                         printf( ((grid[x][y] & S) !=  0)?" ":"_");
  185.                         if((grid[x][y] & E) != 0){
  186.                                 printf((( (grid[x][y] | grid[x + 1][y]) & S) != 0) ?" ":"_");
  187.                         } else {
  188.                                 printf("|");
  189.                         }
  190.                 }
  191.                 printf("\n");
  192.         }*/
  193.         bool grid2[WIDTH*2+1][HEIGHT*2+1];
  194.         bool temp[WIDTH*2+1][HEIGHT*2+1];
  195.         memset(&temp[0], 0, sizeof(temp));
  196.         for (int i=0;i<WIDTH*2+1;i++)
  197.         {
  198.                 block_a(img,i,0,0);
  199.                 grid2[i][0]=0;
  200.         }
  201.         for (int j=0;j<HEIGHT;j++)
  202.         {
  203.                 block_a(img,0,j*2+1,0);
  204.                 block_a(img,0,j*2+2,0);
  205.                 grid2[0][j*2+1]=0;
  206.                 for (int i=0;i<WIDTH;i++)
  207.                 {
  208.                         if((grid[i][j]&E)!=0&&(grid[i][j]&S)==0)
  209.                         {
  210.                                 block_a(img,i*2+1,j*2+1,1);
  211.                                 block_a(img,i*2+1,j*2+2,0);
  212.                                 block_a(img,i*2+2,j*2+1,1);
  213.                                 block_a(img,i*2+2,j*2+2,0);
  214.                                 grid2[i*2+1][j*2+1]=1;
  215.                                 grid2[i*2+1][j*2+2]=0;
  216.                                 grid2[i*2+2][j*2+1]=1;
  217.                                 grid2[i*2+2][j*2+2]=0;
  218.                         }
  219.                         else if((grid[i][j]&E)==0&&(grid[i][j]&S)!=0)
  220.                         {
  221.                                 block_a(img,i*2+1,j*2+1,1);
  222.                                 block_a(img,i*2+1,j*2+2,1);
  223.                                 block_a(img,i*2+2,j*2+1,0);
  224.                                 block_a(img,i*2+2,j*2+2,0);
  225.                                 grid2[i*2+1][j*2+1]=1;
  226.                                 grid2[i*2+1][j*2+2]=1;
  227.                                 grid2[i*2+2][j*2+1]=0;
  228.                                 grid2[i*2+2][j*2+2]=0;
  229.                         }
  230.                         else if((grid[i][j]&E)!=0&&(grid[i][j]&S)!=0)
  231.                         {
  232.                                 block_a(img,i*2+1,j*2+1,1);
  233.                                 block_a(img,i*2+1,j*2+2,1);
  234.                                 block_a(img,i*2+2,j*2+1,1);
  235.                                 block_a(img,i*2+2,j*2+2,0);
  236.                                 grid2[i*2+1][j*2+1]=1;
  237.                                 grid2[i*2+1][j*2+2]=1;
  238.                                 grid2[i*2+2][j*2+1]=1;
  239.                                 grid2[i*2+2][j*2+2]=0;
  240.                         }
  241.                         else
  242.                         {
  243.                                 block_a(img,i*2+1,j*2+1,1);
  244.                                 block_a(img,i*2+1,j*2+2,0);
  245.                                 block_a(img,i*2+2,j*2+1,0);
  246.                                 block_a(img,i*2+2,j*2+2,0);
  247.                                 grid2[i*2+1][j*2+1]=1;
  248.                                 grid2[i*2+1][j*2+2]=0;
  249.                                 grid2[i*2+2][j*2+1]=0;
  250.                                 grid2[i*2+2][j*2+2]=0;
  251.                         }
  252.                 }
  253.         }
  254.         for (int i=0;i<HEIGHT*2+1;i++)
  255.         {
  256.                 block_a(img,WIDTH*2,i,0);
  257.         }
  258.         block_a(img,1,0,1);
  259.         grid2[1][0]=1;
  260.         block_a(img,WIDTH*2-1,0,1);
  261.         grid2[WIDTH*2-1][HEIGHT*2]=1;
  262.         IplImage* img2=cvCloneImage(img);
  263.         main_role=cvPoint(1,0);
  264.         cvSaveImage("maze_origin.bmp",img);
  265.         maze_origin=cvCloneImage(img);
  266.         if(!image)
  267.                 mark_path(img,1,0,WIDTH*2-1,0,grid2,temp);
  268.         else
  269.         {
  270.                 for (int i=0;i<image->width;i++)
  271.                 {
  272.                         for (int j=0;j<image->height;j++)
  273.                         {
  274.                                 unsigned char z=image->imageData[j*image->widthStep+i];
  275.                                 if(z==255)
  276.                                 {
  277.                                         block_a(img,i,j,1,cvScalar(255));
  278.                                 }
  279.                         }
  280.                 }
  281.                 block_a(img,1,0,1,cvScalar(255));
  282.                 block_a(img,WIDTH*2-1,0,1,cvScalar(255));
  283.         }
  284.         if(!image)
  285.         {
  286.                 while(1)       
  287.                 {
  288.                         cvCopyImage(img,img2);
  289.                         cvRectangle(img2,cvPoint(main_role.x*block,main_role.y*block),cvPoint(main_role.x*block+block-1,main_role.y*block+block-1),cvScalar(0,0,255),-1);
  290.                         cvRectangle(img,cvPoint(main_role.x*block,main_role.y*block),cvPoint(main_role.x*block+block-1,main_role.y*block+block-1),cvScalar(255,0,0),-1);
  291.                         cvShowImage("maze",img2);
  292.                         char c=cvWaitKey(0);
  293.                         switch(c)
  294.                         {
  295.                         case 'a':
  296.                                 if(grid2[main_role.x-1][main_role.y]&&main_role.x>0)
  297.                                         main_role.x--;
  298.                                 break;
  299.                         case 'd':
  300.                                 if(grid2[main_role.x+1][main_role.y]&&main_role.x<WIDTH*2+1)
  301.                                         main_role.x++;
  302.                                 break;
  303.                         case 's':
  304.                                 if(grid2[main_role.x][main_role.y+1]&&main_role.y<HEIGHT*2+1)
  305.                                         main_role.y++;
  306.                                 break;
  307.                         case 'w':
  308.                                 if(grid2[main_role.x][main_role.y-1]&&main_role.y>0)
  309.                                         main_role.y--;
  310.                                 break;
  311.                         }
  312.                         if(c=='q')
  313.                                 break;
  314.                 }
  315.         }
  316.         else
  317.         {
  318.                 cvSaveImage("maze.bmp",img);
  319.                 maze=cvCloneImage(img);
  320.         }
  321.         return 1;
  322. }
  323. int dither[4]={0,2,3,1};
  324. int ditherMatrix(unsigned int x,unsigned int y,int c)
  325. {
  326.         if(c>0)
  327.                 return 4*ditherMatrix(x,y,c-1)+dither[(x>>(c))%2+(y>>(c))%2*2];
  328.         else
  329.                 return dither[(x>>(c))%2+(y>>(c))%2*2];
  330. }
  331. CvPoint2D32f hil[4]={cvPoint2D32f(-0.5,-0.5),cvPoint2D32f(-0.5,0.5),cvPoint2D32f(0.5,0.5),cvPoint2D32f(0.5,-0.5)};
  332. vector<CvPoint> vP;

  333. void hilbert(IplImage* img,CvPoint c,int order,int character,bool z)
  334. {
  335.         if(order==2)
  336.         {
  337.                 vP.push_back(cvPoint(c.x,c.y));
  338.         }
  339.         else
  340.         {
  341.                 if(order==4)
  342.                 {
  343.                         int x=c.x/order+img->width/2;
  344.                         int y=c.y/order+img->height/2;
  345.                         if(x>=0&&x<img->width&&y>=0&&y<img->height)
  346.                         {
  347.                                 if(img->imageData[(int)(y*img->widthStep+x)]==(char)(unsigned char)(z?255:0))
  348.                                 {
  349.                                         switch(character)
  350.                                         {
  351.                                         case 0:
  352.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  353.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,0,z);
  354.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,0,z);
  355.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  356.                                                 break;
  357.                                         case 1:
  358.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  359.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,1,z);
  360.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,1,z);
  361.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  362.                                                 break;
  363.                                         case 2:
  364.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  365.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,2,z);
  366.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,2,z);
  367.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  368.                                                 break;
  369.                                         case 3:
  370.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  371.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,3,z);
  372.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,3,z);
  373.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  374.                                                 break;
  375.                                         }
  376.                                 }
  377.                                 else
  378.                                 {
  379.                                         switch(character)
  380.                                         {
  381.                                         case 0:
  382.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  383.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  384.                                                 break;
  385.                                         case 1:
  386.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  387.                                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  388.                                                 break;
  389.                                         case 2:
  390.                                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  391.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  392.                                                 break;
  393.                                         case 3:
  394.                                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  395.                                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  396.                                                 break;
  397.                                         }
  398.                                 }
  399.                         }
  400.                         else
  401.                         {
  402.                                 switch(character)
  403.                                 {
  404.                                 case 0:
  405.                                         hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  406.                                         hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  407.                                         break;
  408.                                 case 1:
  409.                                         hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  410.                                         hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  411.                                         break;
  412.                                 case 2:
  413.                                         hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  414.                                         hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  415.                                         break;
  416.                                 case 3:
  417.                                         hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  418.                                         hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  419.                                         break;
  420.                                 }
  421.                         }
  422.                 }
  423.                 else
  424.                 {
  425.                         switch(character)
  426.                         {
  427.                         case 0:
  428.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,3,z);
  429.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,0,z);
  430.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,0,z);
  431.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,1,z);
  432.                                 break;
  433.                         case 1:
  434.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,2,z);
  435.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,1,z);
  436.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,1,z);
  437.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,0,z);
  438.                                 break;
  439.                         case 2:
  440.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,1,z);
  441.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,2,z);
  442.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,2,z);
  443.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,3,z);
  444.                                 break;
  445.                         case 3:
  446.                                 hilbert(img,cvPoint(hil[0].x*order/2+c.x,hil[0].y*order/2+c.y),order/2,0,z);
  447.                                 hilbert(img,cvPoint(hil[3].x*order/2+c.x,hil[3].y*order/2+c.y),order/2,3,z);
  448.                                 hilbert(img,cvPoint(hil[2].x*order/2+c.x,hil[2].y*order/2+c.y),order/2,3,z);
  449.                                 hilbert(img,cvPoint(hil[1].x*order/2+c.x,hil[1].y*order/2+c.y),order/2,2,z);
  450.                                 break;
  451.                         }
  452.                 }
  453.         }
  454.        
  455. }
  456. bool check_va(IplImage* image, int x,int y)
  457. {
  458.         return x>=0&&x<image->width&&y>=0&&y<image->height;
  459. }
  460. unsigned char check_value(IplImage* image,int x,int y)
  461. {
  462.         return image->imageData[y*image->widthStep+x];
  463. }
  464. /*
  465. int check_in(IplImage* image,int x,int y)
  466. {
  467.         int now=-1,left=-1,right=-1,up=-1,down=-1;
  468.         if(check_va(image,x,y))
  469.         {
  470.                 now=check_value(image,x,y);
  471.         }
  472.         if(check_va(image,x-1,y))
  473.         {
  474.                 left=check_value(image,x-1,y);
  475.         }
  476.         if(check_va(image,x+1,y))
  477.         {
  478.                 right=check_value(image,x+1,y);
  479.         }
  480.         if(check_va(image,x,y-1))
  481.         {
  482.                 up=check_value(image,x,y-1);
  483.         }
  484.         if(check_va(image,x,y+1))
  485.         {
  486.                 down=check_value(image,x,y+1);
  487.         }
  488.         int r=0;
  489.         if(left==255)
  490.         {
  491.                 r=r|W;
  492.         }
  493.         if(right)
  494.         {
  495.                 r=r|E;
  496.         }
  497.         if(up==255)
  498.         {
  499.                 r=r|N;
  500.         }
  501.         if(down==255)
  502.         {
  503.                 r=r|S;
  504.         }
  505.         if(now==255)
  506.                 return r;
  507.         else
  508.                 return 0;
  509. }*/
  510. IplImage* image2;
  511. void hilbertD(IplImage* ori,IplImage* image,int order)//,int grid[WIDTH][HEIGHT])
  512. {
  513.         image2=cvCloneImage(image);
  514.         vP.clear();
  515.         hilbert(ori,cvPoint(0,0),order,0,0);
  516.         for (int i=0;i<vP.size()-1;i++)
  517.         {
  518.                 cvLine(image2,cvPoint(vP[i].x+image->width/2,vP[i].y+image->height/2),cvPoint(vP[i+1].x+image->width/2,vP[i+1].y+image->height/2),cvScalarAll(255),1);
  519.         }
  520.         cvSaveImage("reverse.jpg",image2);
  521.         cvZero(image);
  522.         vP.clear();
  523.         hilbert(ori,cvPoint(0,0),order,0,1);
  524.         for (int i=0;i<vP.size()-1;i++)
  525.         {
  526.                 cvLine(image,cvPoint(vP[i].x+image->width/2,vP[i].y+image->height/2),cvPoint(vP[i+1].x+image->width/2,vP[i+1].y+image->height/2),cvScalarAll(255),1);
  527.         }
  528.         /*
  529.         for (int i=0;i<WIDTH;i++)
  530.         {
  531.                 for (int j=0;j<HEIGHT;j++)
  532.                 {
  533.                         int x=i*2+1;
  534.                         int y=j*2+1;
  535.                         grid[i][j]=check_in(image,x,y);
  536.                         if(grid[i][j]!=0)
  537.                                 carve_passage_from(i,j,grid);
  538.                 }
  539.         }*/
  540. }
  541. /*
  542. void merge(IplImage* image,char* name)
  543. {
  544.         IplImage** imag=new IplImage*[bits-8];
  545.         IplImage* total=cvCreateImage(cvSize(256*(bits-7),256),8,image->nChannels);
  546.         imag[0]=cvCreateImage(cvSize(image->width/2,image->height/2),8,image->nChannels);
  547.         cvResize(image,imag[0]);
  548.         for (int i=1;i<bits-8;i++)
  549.         {
  550.                 imag[i]=cvCreateImage(cvSize(imag[i-1]->width/2,imag[i-1]->height/2),8,image->nChannels);
  551.                 cvResize(imag[i-1],imag[i]);
  552.         }
  553.         for (int x=-128;x<128;x++)
  554.         {
  555.                 for (int y=-128;y<128;y++)
  556.                 {
  557.                         int x0=x+image->width/2;
  558.                         int y0=y+image->height/2;
  559.                         int xt=x+128;
  560.                         int yt=y+128;
  561.                         for(int k=0;k<3;k++)
  562.                                 total->imageData[yt*total->widthStep+xt*image->nChannels+k]=image->imageData[image->widthStep*y0+x0*image->nChannels+k];
  563.                 }
  564.         }
  565.         for (int i=0;i<bits-8;i++)
  566.         {
  567.                 for (int x=-128;x<128;x++)
  568.                 {
  569.                         for (int y=-128;y<128;y++)
  570.                         {
  571.                                 int x0=x+imag[i]->width/2;
  572.                                 int y0=y+imag[i]->height/2;
  573.                                 int xt=x+i*256+128+256;
  574.                                 int yt=y+128;
  575.                                 for(int k=0;k<3;k++)
  576.                                         total->imageData[yt*total->widthStep+xt*image->nChannels+k]=imag[i]->imageData[imag[i]->widthStep*y0+x0*image->nChannels+k];
  577.                         }
  578.                 }
  579.         }
  580.         cvSaveImage(name,total);
  581.         cvReleaseImage(&total);
  582.         for (int i=0;i<bits-8;i++)
  583.         {
  584.                 cvReleaseImage(&imag[i]);
  585.         }
  586. }*/
  587. int _tmain(int argc, _TCHAR* argv[])
  588. {
  589.         init();
  590.         IplImage* hill=cvCreateImage(cvSize((1<<bits),(1<<bits)),8,1);
  591.         IplImage* origin0=cvLoadImage("m.bmp",0);
  592.         cvSaveImage("D:\\gray.jpg", origin0);
  593.         double ratio=origin0->width>origin0->height?origin0->width/(double)(1<<(bits-2)):origin0->height/(double)(1<<(bits-2));
  594.         IplImage* origin=cvCreateImage(cvSize(origin0->width/ratio,origin0->height/ratio),8,1);
  595.         cvResize(origin0,origin);
  596.         IplImage* tempi=cvCloneImage(origin);
  597.         IplImage* tempi2=cvCloneImage(origin);
  598.         int c=3;
  599.         double gray=256/(double)(1<<(2*c));
  600.         for (int x=0;x<origin->width;x++)
  601.         {
  602.                 for (int y=0;y<origin->height;y++)
  603.                 {
  604.                         unsigned char g=origin->imageData[y*origin->widthStep+x];
  605.                         tempi->imageData[y*tempi->widthStep+x]=g/gray>ditherMatrix(x%(1<<(c-1)),y%(1<<(c-1)),c-1)?(char)(unsigned char)255:(char)(unsigned char)0;
  606.                 }
  607.         }
  608.         cvSaveImage("D:\\bw.jpg", tempi);
  609.         cvShowImage("origin",origin);
  610.         cvShowImage("origin",tempi);
  611.         hilbertD(tempi,hill,(1<<bits));
  612.         cvSaveImage("D:\\hilbert.png", hill);
  613.         cvShowImage("hilbert",hill);
  614. //        cvSaveImage("hilbert.bmp",hill);
  615.         cvWaitKey(0);
  616.         /*
  617.         img=cvCreateImage(cvSize(block*(WIDTH*2+1),block*(HEIGHT*2+1)),8,3);
  618.         generate(hill);
  619.         merge(image2,"hibertD.jpg");
  620.         merge(maze,"mazeD.jpg");
  621.         merge(maze_origin,"maze_originD.jpg");
  622.        
  623.         */
  624.           return 0;
  625. }

复制代码



顺便提一句...
QQ图片20161003032714.jpg
论坛的图片分辨率还是小垃圾一个...无法看清分形图案的全貌,所以有任何朋友需要高清女神图像...q我。
qq:1174686650
验证问题忽略掉。


原创帖,转载请注明出处。

评分

参与人数 1 +3 收起 理由
幻生幻灭 + 3 学习的动力,请把链接私信我=3=,共同进步

查看全部评分

回复

使用道具 举报

发表于 2016-10-3 08:23:48 来自手机 | 显示全部楼层
好神奇的东西…先收了!
回复 支持 反对

使用道具 举报

发表于 2016-10-3 14:29:50 | 显示全部楼层
果然女神是进步的动力源泉233333
回复 支持 反对

使用道具 举报

发表于 2016-10-3 21:19:58 | 显示全部楼层
太厉害了吧!点开实际效果,方识庐山真面目!!!赞,期待后续帖子和应用。
顺便说一句,有python版的吗
回复 支持 反对

使用道具 举报

发表于 2016-10-3 21:53:03 | 显示全部楼层
求系列教程 让小白长知识
回复 支持 反对

使用道具 举报

发表于 2016-10-9 15:51:51 | 显示全部楼层
高手,流弊啊
回复 支持 反对

使用道具 举报

发表于 2016-11-25 20:13:31 | 显示全部楼层
嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿
回复 支持 反对

使用道具 举报

发表于 2017-5-13 12:03:49 | 显示全部楼层
硬件是什么?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-7-9 20:35 , Processed in 0.061208 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表