这个其实就是从csdn上面下载的一个例程。感谢这位同学的总结,与源码的有偿分享。

本随笔就是把它通过4个随笔的拆分,实现的。

可以通过:

http://blog.csdn.net/masibuaa/article/details/9246493这个地方自己反推,因为原博客是通过qt实现的,并且并没有共享全部的代码,所以不是很好理解。

学习还是要所见即所得才行。

所以我又去下载了一个在vs2010平台上面能跑的程序。

然后在vs2015的上面实现了。

接下来就可以踏实一阵儿了。

main.cpp:

  1. #include <iostream>//这个位置 貌似没那么严格
  2. #include "opencv2/highgui/highgui.hpp"//这个是基本类库,高级图形用户接口,必须要引入
  3. #include "opencv2/core/core.hpp"
  4. #include <imgproc\imgproc_c.h>
  5.  
  6. extern "C"
  7. {
  8. #include "imgfeatures.h"
  9. #include "kdtree.h"
  10. #include "minpq.h"
  11. #include "sift.h"
  12. #include "utils.h"
  13. #include "xform.h"
  14. }
  15.  
  16. //在k-d树上进行BBF搜索的最大次数
  17. /* the maximum number of keypoint NN candidates to check during BBF search */
  18. #define KDTREE_BBF_MAX_NN_CHKS 200
  19.  
  20. //目标点与最近邻和次近邻的距离的比值的阈值,若大于此阈值,则剔除此匹配点对
  21. //通常此值取0.6,值越小找到的匹配点对越精确,但匹配数目越少
  22. /* threshold on squared ratio of distances between NN and 2nd NN */
  23. //#define NN_SQ_DIST_RATIO_THR 0.49
  24. #define NN_SQ_DIST_RATIO_THR 0.5
  25.  
  26. using namespace std;
  27. using namespace cv;
  28.  
  29. //计算图2的四个角经矩阵H变换后的坐标
  30. void CalcFourCorner(CvMat* &H, CvPoint& leftTop, CvPoint& leftBottom, CvPoint& rightTop, CvPoint& rightBottom, IplImage* img2)
  31. {
  32. //计算图2的四个角经矩阵H变换后的坐标
  33. double v2[] = { , , };//左上角
  34. double v1[];//变换后的坐标值
  35. CvMat V2 = cvMat(, , CV_64FC1, v2);
  36. CvMat V1 = cvMat(, , CV_64FC1, v1);
  37. cvGEMM(H, &V2, , , , &V1);//矩阵乘法
  38. leftTop.x = cvRound(v1[] / v1[]);
  39. leftTop.y = cvRound(v1[] / v1[]);
  40. //cvCircle(xformed,leftTop,7,CV_RGB(255,0,0),2);
  41.  
  42. //将v2中数据设为左下角坐标
  43. v2[] = ;
  44. v2[] = img2->height;
  45. V2 = cvMat(, , CV_64FC1, v2);
  46. V1 = cvMat(, , CV_64FC1, v1);
  47. cvGEMM(H, &V2, , , , &V1);
  48. leftBottom.x = cvRound(v1[] / v1[]);
  49. leftBottom.y = cvRound(v1[] / v1[]);
  50. //cvCircle(xformed,leftBottom,7,CV_RGB(255,0,0),2);
  51.  
  52. //将v2中数据设为右上角坐标
  53. v2[] = img2->width;
  54. v2[] = ;
  55. V2 = cvMat(, , CV_64FC1, v2);
  56. V1 = cvMat(, , CV_64FC1, v1);
  57. cvGEMM(H, &V2, , , , &V1);
  58. rightTop.x = cvRound(v1[] / v1[]);
  59. rightTop.y = cvRound(v1[] / v1[]);
  60. //cvCircle(xformed,rightTop,7,CV_RGB(255,0,0),2);
  61.  
  62. //将v2中数据设为右下角坐标
  63. v2[] = img2->width;
  64. v2[] = img2->height;
  65. V2 = cvMat(, , CV_64FC1, v2);
  66. V1 = cvMat(, , CV_64FC1, v1);
  67. cvGEMM(H, &V2, , , , &V1);
  68. rightBottom.x = cvRound(v1[] / v1[]);
  69. rightBottom.y = cvRound(v1[] / v1[]);
  70. //cvCircle(xformed,rightBottom,7,CV_RGB(255,0,0),2);
  71.  
  72. }
  73.  
  74. int detectionFeature(IplImage* img, struct feature*& feat)
  75. {
  76. int n = sift_features(img, &feat);//检测图img中的SIFT特征点,n是图的特征点个数
  77. //export_features("feature.txt",feat,n);//将特征向量数据写入到文件
  78. return n;
  79. }
  80. IplImage* spliceImage(IplImage* img1, IplImage* img2)
  81. {
  82. struct feature *feat1, *feat2;//feat1:图1的特征点数组,feat2:图2的特征点数组
  83. int n1, n2;//n1:图1中的特征点个数,n2:图2中的特征点个数
  84. struct feature *feat;//每个特征点
  85. struct kd_node *kd_root;//k-d树的树根
  86. struct feature **nbrs;//当前特征点的最近邻点数组
  87. CvMat * H = NULL;//RANSAC算法求出的变换矩阵
  88. struct feature **inliers;//精RANSAC筛选后的内点数组
  89. int n_inliers;//经RANSAC算法筛选后的内点个数,即feat2中具有符合要求的特征点的个数
  90.  
  91. IplImage *xformed = NULL, *xformed_proc = NULL;//xformed临时拼接图,即只将图2变换后的图,xformed_proc是最终合成的图
  92.  
  93. //图2的四个角经矩阵H变换后的坐标
  94. CvPoint leftTop, leftBottom, rightTop, rightBottom;
  95. ///////////////////////////////////////////////////////////////////
  96.  
  97. //特征点检测
  98. n1 = detectionFeature(img1, feat1);//检测图1中的SIFT特征点,n1是图1的特征点个数
  99. //提取并显示第2幅图片上的特征点
  100. n2 = detectionFeature(img2, feat2);//检测图2中的SIFT特征点,n2是图2的特征点个数
  101.  
  102. //特征匹配
  103. //方式一:水平排列
  104. //将2幅图片合成1幅图片,img1在左,img2在右
  105. //stacked = stack_imgs_horizontal(img1, img2);//合成图像,显示经距离比值法筛选后的匹配结果
  106. //根据图1的特征点集feat1建立k-d树,返回k-d树根给kd_root
  107. kd_root = kdtree_build(feat1, n1);
  108. CvPoint pt1, pt2;//连线的两个端点
  109. double d0, d1;//feat2中每个特征点到最近邻和次近邻的距离
  110. int matchNum = ;//经距离比值法筛选后的匹配点对的个数
  111. //遍历特征点集feat2,针对feat2中每个特征点feat,选取符合距离比值条件的匹配点,放到feat的fwd_match域中
  112. for (int i = ; i < n2; i++)
  113. {
  114. feat = feat2 + i;//第i个特征点的指针
  115. //在kd_root中搜索目标点feat的2个最近邻点,存放在nbrs中,返回实际找到的近邻点个数
  116. int k = kdtree_bbf_knn(kd_root, feat, , &nbrs, KDTREE_BBF_MAX_NN_CHKS);
  117. if (k == )
  118. {
  119. d0 = descr_dist_sq(feat, nbrs[]);//feat与最近邻点的距离的平方
  120. d1 = descr_dist_sq(feat, nbrs[]);//feat与次近邻点的距离的平方
  121. //若d0和d1的比值小于阈值NN_SQ_DIST_RATIO_THR,则接受此匹配,否则剔除
  122. if (d0 < d1 * NN_SQ_DIST_RATIO_THR)
  123. { //将目标点feat和最近邻点作为匹配点对
  124. pt2.x = cvRound(feat->x); pt2.y = cvRound(feat->y);
  125. pt1.x = cvRound(nbrs[]->x); pt1.y = cvRound(nbrs[]->y);
  126. pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点
  127. //cvLine( stacked, pt1, pt2, CV_RGB(255,0,255), 1, 8, 0 );//画出连线
  128. matchNum++;//统计匹配点对的个数
  129. feat2[i].fwd_match = nbrs[];//使点feat的fwd_match域指向其对应的匹配点
  130. }
  131. }
  132. free(nbrs);//释放近邻数组
  133. }
  134. //利用RANSAC算法筛选匹配点,计算变换矩阵H,
  135. //无论img1和img2的左右顺序,H永远是将feat2中的特征点变换为其匹配点,即将img2中的点变换为img1中的对应点
  136. H = ransac_xform(feat2, n2, FEATURE_FWD_MATCH, lsq_homog, , 0.01, homog_xfer_err, 3.0, &inliers, &n_inliers);
  137.  
  138. //若能成功计算出变换矩阵,即两幅图中有共同区域
  139. IplImage* stacked_ransac;
  140.  
  141. ///stacked_ransac = stack_imgs(img1, img2);
  142. stacked_ransac = stack_imgs_horizontal(img1, img2);
  143.  
  144. if (H)
  145. {
  146. int invertNum = ;//统计pt2.x > pt1.x的匹配点对的个数,来判断img1中是否右图
  147.  
  148. //遍历经RANSAC算法筛选后的特征点集合inliers,找到每个特征点的匹配点,画出连线
  149. for (int i = ; i<n_inliers; i++)
  150. {
  151. feat = inliers[i];//第i个特征点
  152. pt2 = cvPoint(cvRound(feat->x), cvRound(feat->y));//图2中点的坐标
  153. pt1 = cvPoint(cvRound(feat->fwd_match->x), cvRound(feat->fwd_match->y));//图1中点的坐标(feat的匹配点)
  154.  
  155. //统计匹配点的左右位置关系,来判断图1和图2的左右位置关系
  156. if (pt2.x > pt1.x)
  157. invertNum++;
  158.  
  159. // pt2.y += img1->height;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点
  160. pt2.x += img1->width;//由于两幅图是左右排列的,pt2的横坐标加上图1的宽度,作为连线的终点
  161. cvLine(stacked_ransac, pt1, pt2, CV_RGB(, , ), , , );//在匹配图上画出连线
  162. }
  163. cvNamedWindow("IMG_MATCH2");//创建窗口
  164. cvShowImage("IMG_MATCH2", stacked_ransac);//显示经RANSAC算法筛选后的匹配图
  165. }
  166.  
  167. if (H)
  168. {
  169. //全景拼接
  170. //若能成功计算出变换矩阵,即两幅图中有共同区域,才可以进行全景拼接
  171. //拼接图像,img1是左图,img2是右图
  172. CalcFourCorner(H, leftTop, leftBottom, rightTop, rightBottom, img2);//计算图2的四个角经变换后的坐标
  173. //为拼接结果图xformed分配空间,高度为图1图2高度的较小者,根据图2右上角和右下角变换后的点的位置决定拼接图的宽度
  174. xformed = cvCreateImage(cvSize(MIN(rightTop.x, rightBottom.x), MIN(img1->height, img2->height)), IPL_DEPTH_8U, );
  175. //用变换矩阵H对右图img2做投影变换(变换后会有坐标右移),结果放到xformed中
  176. cvWarpPerspective(img2, xformed, H, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll());
  177.  
  178. //处理后的拼接图,克隆自xformed
  179. xformed_proc = cvCloneImage(xformed);
  180.  
  181. //重叠区域左边的部分完全取自图1
  182. cvSetImageROI(img1, cvRect(, , MIN(leftTop.x, leftBottom.x), xformed_proc->height));
  183. cvSetImageROI(xformed, cvRect(, , MIN(leftTop.x, leftBottom.x), xformed_proc->height));
  184. cvSetImageROI(xformed_proc, cvRect(, , MIN(leftTop.x, leftBottom.x), xformed_proc->height));
  185. cvAddWeighted(img1, , xformed, , , xformed_proc);
  186. cvResetImageROI(img1);
  187. cvResetImageROI(xformed);
  188. cvResetImageROI(xformed_proc);
  189.  
  190. ////////////////////////////////////////////////////////////
  191. //图像融合
  192. //采用加权平均的方法融合重叠区域
  193. int start = MIN(leftTop.x, leftBottom.x);//开始位置,即重叠区域的左边界
  194. double processWidth = img1->width - start;//重叠区域的宽度
  195. double alpha = ;//img1中像素的权重
  196. for (int i = ; i<xformed_proc->height; i++)//遍历行
  197. {
  198. const uchar * pixel_img1 = ((uchar *)(img1->imageData + img1->widthStep * i));//img1中第i行数据的指针
  199. const uchar * pixel_xformed = ((uchar *)(xformed->imageData + xformed->widthStep * i));//xformed中第i行数据的指针
  200. uchar * pixel_xformed_proc = ((uchar *)(xformed_proc->imageData + xformed_proc->widthStep * i));//xformed_proc中第i行数据的指针
  201. for (int j = start; j<img1->width; j++)//遍历重叠区域的列
  202. {
  203. //如果遇到图像xformed中无像素的黑点,则完全拷贝图1中的数据
  204. if (pixel_xformed[j * ] < && pixel_xformed[j * + ] < && pixel_xformed[j * + ] < )
  205. {
  206. alpha = ;
  207. }
  208. else
  209. { //img1中像素的权重,与当前处理点距重叠区域左边界的距离成正比
  210. alpha = (processWidth - (j - start)) / processWidth;
  211. }
  212. pixel_xformed_proc[j * ] = pixel_img1[j * ] * alpha + pixel_xformed[j * ] * ( - alpha);//B通道
  213. pixel_xformed_proc[j * + ] = pixel_img1[j * + ] * alpha + pixel_xformed[j * + ] * ( - alpha);//G通道
  214. pixel_xformed_proc[j * + ] = pixel_img1[j * + ] * alpha + pixel_xformed[j * + ] * ( - alpha);//R通道
  215. }
  216. }
  217.  
  218. }
  219. else //无法计算出变换矩阵,即两幅图中没有重合区域
  220. {
  221. return NULL;
  222. }
  223. ///////////////////////////////////////////////////////////////////////////
  224. kdtree_release(kd_root);//释放kd树
  225. //只有在RANSAC算法成功算出变换矩阵时,才需要进一步释放下面的内存空间
  226. if (H)
  227. {
  228. cvReleaseMat(&H);//释放变换矩阵H
  229. free(inliers);//释放内点数组
  230. }
  231. if (NULL != xformed)
  232. {
  233. cvReleaseImage(&xformed);
  234. }
  235. return xformed_proc;
  236. }
  237.  
  238. void match(IplImage *img1, IplImage *img2)
  239. {
  240. IplImage *img1_Feat = cvCloneImage(img1);//复制图1,深拷贝,用来画特征点
  241. IplImage *img2_Feat = cvCloneImage(img2);//复制图2,深拷贝,用来画特征点
  242.  
  243. struct feature *feat1, *feat2;//feat1:图1的特征点数组,feat2:图2的特征点数组
  244. int n1, n2;//n1:图1中的特征点个数,n2:图2中的特征点个数
  245. struct feature *feat;//每个特征点
  246. struct kd_node *kd_root;//k-d树的树根
  247. struct feature **nbrs;//当前特征点的最近邻点数组
  248. int matchNum;//经距离比值法筛选后的匹配点对的个数
  249. struct feature **inliers;//精RANSAC筛选后的内点数组
  250. int n_inliers;//经RANSAC算法筛选后的内点个数,即feat1中具有符合要求的特征点的个数
  251.  
  252. //默认提取的是LOWE格式的SIFT特征点
  253. //提取并显示第1幅图片上的特征点
  254. n1 = sift_features(img1, &feat1);//检测图1中的SIFT特征点,n1是图1的特征点个数
  255. export_features("feature1.txt", feat1, n1);//将特征向量数据写入到文件
  256. draw_features(img1_Feat, feat1, n1);//画出特征点
  257. cvShowImage("img1_Feat", img1_Feat);//显示
  258.  
  259. //提取并显示第2幅图片上的特征点
  260. n2 = sift_features(img2, &feat2);//检测图2中的SIFT特征点,n2是图2的特征点个数
  261. export_features("feature2.txt", feat2, n2);//将特征向量数据写入到文件
  262. draw_features(img2_Feat, feat2, n2);//画出特征点
  263. cvShowImage("img2_Feat", img2_Feat);//显示
  264.  
  265. Point pt1, pt2;//连线的两个端点
  266. double d0, d1;//feat1中每个特征点到最近邻和次近邻的距离
  267. matchNum = ;//经距离比值法筛选后的匹配点对的个数
  268.  
  269. IplImage* stacked;
  270. IplImage* stacked_ransac;
  271. //将2幅图片合成1幅图片,上下排列
  272. stacked = stack_imgs(img1, img2);//合成图像,显示经距离比值法筛选后的匹配结果
  273. stacked_ransac = stack_imgs(img1, img2);//合成图像,显示经RANSAC算法筛选后的匹配结果
  274.  
  275. //根据图2的特征点集feat2建立k-d树,返回k-d树根给kd_root
  276. kd_root = kdtree_build(feat2, n2);
  277.  
  278. //遍历特征点集feat1,针对feat1中每个特征点feat,选取符合距离比值条件的匹配点,放到feat的fwd_match域中
  279. for (int i = ; i < n1; i++)
  280. {
  281. feat = feat1 + i;//第i个特征点的指针
  282. //在kd_root中搜索目标点feat的2个最近邻点,存放在nbrs中,返回实际找到的近邻点个数
  283. int k = kdtree_bbf_knn(kd_root, feat, , &nbrs, KDTREE_BBF_MAX_NN_CHKS);
  284. if (k == )
  285. {
  286. d0 = descr_dist_sq(feat, nbrs[]);//feat与最近邻点的距离的平方
  287. d1 = descr_dist_sq(feat, nbrs[]);//feat与次近邻点的距离的平方
  288. //若d0和d1的比值小于阈值NN_SQ_DIST_RATIO_THR,则接受此匹配,否则剔除
  289. if (d0 < d1 * NN_SQ_DIST_RATIO_THR)
  290. { //将目标点feat和最近邻点作为匹配点对
  291. pt1 = Point(cvRound(feat->x), cvRound(feat->y));//图1中点的坐标
  292. pt2 = Point(cvRound(nbrs[]->x), cvRound(nbrs[]->y));//图2中点的坐标(feat的最近邻点)
  293. pt2.y += img1->height;//由于两幅图是上下排列的,pt2的纵坐标加上图1的高度,作为连线的终点
  294. cvLine(stacked, pt1, pt2, CV_RGB(, , ), , , );//画出连线
  295. matchNum++;//统计匹配点对的个数
  296. feat1[i].fwd_match = nbrs[];//使点feat的fwd_match域指向其对应的匹配点
  297. }
  298. }
  299. free(nbrs);//释放近邻数组
  300. }
  301. //qDebug() << tr("经距离比值法筛选后的匹配点对个数:") << matchNum << endl;
  302. cout << "经距离比值法筛选后的匹配点对个数:" << matchNum << endl;
  303. //显示并保存经距离比值法筛选后的匹配图
  304. cvNamedWindow("IMG_MATCH1", );//创建窗口
  305. cvShowImage("IMG_MATCH1", stacked);//显示
  306.  
  307. //利用RANSAC算法筛选匹配点,计算变换矩阵H
  308. CvMat * H = ransac_xform(feat1, n1, FEATURE_FWD_MATCH, lsq_homog, , 0.01, homog_xfer_err, 3.0, &inliers, &n_inliers);
  309. //qDebug() << tr("经RANSAC算法筛选后的匹配点对个数:") << n_inliers << endl;
  310. cout << "经RANSAC算法筛选后的匹配点对个数:" << matchNum << endl;
  311. //遍历经RANSAC算法筛选后的特征点集合inliers,找到每个特征点的匹配点,画出连线
  312. for (int i = ; i<n_inliers; i++)
  313. {
  314. feat = inliers[i];//第i个特征点
  315. pt1 = Point(cvRound(feat->x), cvRound(feat->y));//图1中点的坐标
  316. pt2 = Point(cvRound(feat->fwd_match->x), cvRound(feat->fwd_match->y));//图2中点的坐标(feat的匹配点)
  317. //qDebug() << "(" << pt1.x << "," << pt1.y << ")--->(" << pt2.x << "," << pt2.y << ")" << endl;
  318. cout << "(" << pt1.x << "," << pt1.y << ")--->(" << pt2.x << "," << pt2.y << ")" << endl;
  319. pt2.y += img1->height;//由于两幅图是上下排列的,pt2的纵坐标加上图1的高度,作为连线的终点
  320. cvLine(stacked_ransac, pt1, pt2, CV_RGB(, , ), , , );//画出连线
  321. }
  322. cvNamedWindow("IMG_MATCH2",);//创建窗口
  323. cvShowImage("IMG_MATCH2", stacked_ransac);//显示
  324.  
  325. IplImage* xformed_proc12 = NULL;
  326.  
  327. xformed_proc12 = spliceImage(img1, img2);
  328. if (NULL != xformed_proc12)
  329. {
  330. cvNamedWindow("拼接后", );//创建窗口
  331. cvShowImage("拼接后", xformed_proc12);//显示处理后的拼接图
  332. cvSaveImage("gg12345678.jpg", xformed_proc12);
  333. cvWaitKey();
  334. }
  335.  
  336. }
  337.  
  338. int main(){
  339.  
  340. IplImage * img1 = cvLoadImage("l4.png");
  341. IplImage * img2 = cvLoadImage("r4.png");
  342.  
  343. match(img1, img2);
  344.  
  345. cvWaitKey();
  346.  
  347. }

还有12个文件,前面已经反复复制粘贴过了。应该不用描述了,总之把它们写入到对应的头文件和原文件里面,就可以执行了。

vs中两张图片的融合的更多相关文章

  1. 实现ImageView中两张图片重叠显示

    第一种XML配置 使用layer-list标签 <layer-list xmlns:android="http://schemas.android.com/apk/res/androi ...

  2. 1) 上传多张图片时 ,对 $_FILES 的处理. upload ; 2)fileinput 上传多张图片. 3) 修改,删除的时候删除原来的资源,图片 update, delete , 删除 4)生成器中两个字段上传图片的时候,要修改生成器生成的代码

    1上传多张图片, 要对 $_FILES进行 重新处理. //添加 public function addCourseAlbumAction() { $CourseAlbumModel = new Co ...

  3. 使用CSS3中Canvas 实现两张图片合成一张图片【常用于合成二维码图片】

    CSS3 Canvas 实现两张图片合成一张图片 需求 需求:在项目中遇到将一张固定图片和一张二维码图片合成一张新图片,并且用户能够将图片保存下载到本地. 思路:使用 CSS3 中的 Canvas 将 ...

  4. OpenCV两张图片的合并

    转载请注明出处..! http://blog.csdn.net/zhonghuan1992 OpenCV两张图片的合并 原理: 两张图片合并,想想图片是用一个个像素点来存储.每一个像素点有他的值. 那 ...

  5. 用python对比两张图片的不同

    from PIL import Image from PIL import ImageChops def compare_images(path_one, path_two, diff_save_lo ...

  6. python实战===用python对比两张图片的不同

    from PIL import Image from PIL import ImageChops def compare_images(path_one, path_two, diff_save_lo ...

  7. OpenCV入门:(四:混合两张图片)

    1. 原理 对两张图片使用如下公式可以得到两张图片的混合图片, 其中f0(x),f1(x)分别是图片1和图片2同一位置的像素点. 2. OpenCV中的AddWeight函数 函数和参数说明: ) s ...

  8. Opencv实现两幅图像融合

    实现两幅图像线性(不同系数下)的融合涉及到Opencv中两个关键的方法,addWeighted()和createTrackbar() addWeighted方法: 函数原型: void addWeig ...

  9. C# 比较两张图片是否完全相同

    本文演示如何比较两张图片是否完全相同. (注意:如果是比较两张图片是否相似,则比较复杂,涉及到机器学习) 方法一:把图片保存到内存流中,然后转化成 Base64 字符串进行比较 using Syste ...

随机推荐

  1. 20150913K-means聚类

    1.聚类的思想: 将一个有N个对象的数据集,构造成k(k<=n)个划分,每个划分代表一个簇.使得每个簇包含一个对象,每个对象有且仅属于一个簇.对于给定的k,算法首先给出一个初始的划分方法,以后通 ...

  2. av_interleaved_write_frame 网络不好的情况下返回较慢

    用libvlc做直播推流引擎在网络较差的情况下,需要关闭直播,并且重新开播.这个过程中,推流引擎重启,需要的是快速响应.实际上测试结果发现,经常会发生引擎关闭接口卡住.后来跟踪代码,定位到s_rtmp ...

  3. 对"一维最大子数组和"问题的思考(homework-01)

    一维最大子数组和问题,即给定一个数组,在它所有的连续子数组的和中,求最大的那个和.“最大子数组和”是一个很好的IT面试考题,在<编程之美>一书中同时阐述了一维数组和二维数组的讨论.本篇博客 ...

  4. jquery easyui鼠标右击显示自定义的菜单

    1.datagrid表格中,对某一行鼠标右击,显示出如下的自定义的菜单: 在html页面中写: <div id="menu" class="easyui-menu& ...

  5. BestCoder Round #67 (div.2) N bulbs(hdu 5600)

    N bulbs Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  6. 发布ASP.NET网站时的设置

    在ASP.NET网站开发完成之后,一般都要进行发布,然后再使用. 点击“目标位置”后的按钮可以选择将网站发布到的位置,有“本地.本机IIS.FTP站点.远程网站站点”四个选项. 另外,发布网站时还有四 ...

  7. Spring的ControllerAdvice注解

    @ControllerAdvice,是spring3.2提供的新注解,其实现如下所示: @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUN ...

  8. jquery 鼠标经过放大图片

    jquery.elevatezoom.js文件请到演示文件查看 演示 JavaScript Code <script type="text/javascript"> $ ...

  9. Debug Tools

    .NET专用调试工具:MDBG .NET的死锁调试工具:ACorns.Debugging WinDBG+SOS(Windows平台下最强DeBug工具,是解决BUG的最后手段)

  10. Python beautifulsoup模块

    BeautifulSoup中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ BeautifulSoup下载:http://w ...