opencv+VS2017自分形学习

来源:互联网 发布:csol一键瞬狙数据 编辑:程序博客网 时间:2024/04/30 05:18

很久没有写过程序了,但是也不想就此放弃,所以从分形图像开始练代码,同时开始学习算法,如果之后能够坚持下去,就开始在GIThub上进行学习

#include "stdafx.h"#include<iostream>#include<opencv\cv.h>#include<opencv2\core\core.hpp>#include<opencv2\opencv.hpp>#include<opencv\highgui.h>#include<vector>using namespace std;using namespace cv;int taoyizhijisuan(double x, double y){    double x0, y0, x1, y1;    double x_a, y_a;    x_a = 0.1;    y_a = 0.2;    x0 = x;    y0 = y;    long int i;    for (i = 1; i<1000; i++)    {        x1 = x0*x0 - y0*y0 + x_a;        y1 = x0*y0 * 2 + y_a;        if ((x1*x1 + y1*y1) > 4)            break;        x0 = x1;        y0 = y1;    }    return i;}int main(){    //Mat pic=Mat::zeros(600,600,CV_8UC3);    Mat pic(600, 600, CV_8UC3);    for (double i = 1; i<600; i ++)    {        for (double j = 1; j<600; j ++)        {            if (taoyizhijisuan((i - 300) / 100, (j - 300) / 100) >= 1000)            {                pic.at<Vec3b>(i, j) = 200;//at函数和vec3b在vector头文件中            }        }    }    pic.at<Vec3b>(120, 220) = 0;    namedWindow("output", CV_WINDOW_AUTOSIZE);    imshow("output", pic);    waitKey();    return 0;}

以上是我重新配置环境后正常运行的第一版代码;过程中发生了两个错误值得记录一下:
1、 at函数

pic.at<Vec3b>(i, j) = 200;//at函数和vec3b在vector头文件中

上面这一行,开始的时候一直报错未找到cv::Mat::at相关函数,但是在网上查找所有的博客都提示该函数是opencv查找某像素点的最简单函数,所以一开始我在想是不是由于我格式写错了,少写了定义域之类的,但是反复核对了其他人的代码,找不到问题,最后灵机一动,是不是由于头文件中没有包含?于是去找了opencv常用头文件,一个一个添加后,终于在下面这行添加上后,这个报错消失了:

#include<vector>

2、输出图像为非分型图像
程序跑通之后,一直显示如下图像
这里写图片描述
很明显,这个并非分型图像,而且边缘地区大约处于x=100,y=200处;手工计算,很快就能发现,这个值是无法满足分型函数的。
我开始在函数中找错误,但是函数没有错误,所有的变量声明也都是double,不可能是由于计算过程中程序约减造成的错误。
过程中反复思考,在以下行下面增加了一个输出函数:

            pic.at<Vec3b>(i, j) = 200;//at函数和vec3b在vector头文件中            cout<<x1<<" "<<endl;

来检查输出值的准确性;
发现确实是在以上x=101,y=201处函数有值,但是手工计算,该处是不应该有值的,手工打断点,然后看值,发现该处初始值x0=1,y0=0;手工计算x0应该为1.9左右,y应该为0.9左右,以上,找到了错误的源头,问题出在遍历图像像素的for函数中,该函数中,使用了int定义每个像素点,但是没有另外定义double的值作为taoyizhijisuan函数的输入值,导致计算过程中全部换算为int,丢失了后面的所有值,修改上面后,输出图圆:
这里写图片描述
修改x_a,y_a的值,输出自分形图像:
这里写图片描述

总结教训:
使用其他人的函数,报错找不到该函数时,检查头文件是否进行了包含;
使用判断函数时,结果中的边界很奇怪时,检查数值类型;

在现阶段,在写程序时,添加所有可能用到的头文件,所有数值类型除特殊需要外,全部写为double,增加程序的冗余,将主要精力放在算法上。