形态学处理函数

  1. #include <cv.h>
  2. #include <highgui.h>
  3. #include <stdio.h>
  4. #define isSIZEEQU(x,y) (((x)->width)==((y)->width)&&((x)->height)==((y)->height))
  5. typedef int DataType;
  6. struct Position_{
  7. int x;
  8. int y;
  9. };
  10. typedef struct Position_ Position;
  11. typedef struct Position_ MoveDirection;
  12. //位移操作,将图像整体移动,如果超出边界舍去
  13. int isEqual(IplImage *src1,IplImage *src2){
  14. if(!isSIZEEQU(src1, src2))
  15. return 0;
  16. int width=src1->width;
  17. int height=src1->height;
  18. for(int i=0;i<width;i++)
  19. for(int j=0;j<height;j++){
  20. int v0=cvGetReal2D(src1, j, i);
  21. int v1=cvGetReal2D(src2, j, i);
  22. if(v0!=v1)
  23. return 0;
  24. }
  25. return 1;
  26. }
  27. //检测图像是否为空
  28. int isEmpty(IplImage *src){
  29. int width=src->width;
  30. int height=src->height;
  31. for(int i=0;i<width;i++)
  32. for(int j=0;j<height;j++){
  33. int v=cvGetReal2D(src, j, i);
  34. if(v!=0.0)
  35. return 0;
  36. }
  37. return 1;
  38. }
  39. void Translation(IplImage *src,IplImage *dst,MoveDirection *direction){
  40. int width=src->width;
  41. int height=src->height;
  42. //printf("%d,%d\n",direction->x,direction->y);
  43. IplImage *temp=cvCreateImage(cvSize(width, height), src->depth, src->nChannels);
  44. cvZero(temp);
  45. for(int i=0;i<width;i++)
  46. for(int j=0;j<height;j++){
  47. if(j+direction->y<height &&
  48. i+direction->x<width  &&
  49. j+direction->y>=0      &&
  50. i+direction->x>=0        )
  51. cvSetReal2D(temp, j+direction->y, i+direction->x, cvGetReal2D(src, j, i));
  52. }
  53. cvCopy(temp, dst, NULL);
  54. cvReleaseImage(&temp);
  55. }
  56. //将小的图像弄到大的黑色图像中间,或者说是给图像加黑色边框
  57. void Zoom(IplImage *src,IplImage *dst){
  58. if(dst->width<src->width         ||
  59. dst->height<src->height       ||
  60. (dst->height-src->height)%2==1||
  61. (dst->width-src->width)%2==1){
  62. if(dst->width<src->width )
  63. printf("Zoom wrong:dst‘s width too small!\n");
  64. if(dst->height<src->height )
  65. printf("Zoom wrong:dst‘s height too small!\n");
  66. if((dst->height-src->height)%2==1||(dst->width-src->width)%2==1)
  67. printf("Zoom wrong:dst-src not a oushu!\n");
  68. exit(0);
  69. }
  70. MoveDirection m;
  71. m.x=(dst->width-src->width)/2;
  72. m.y=(dst->height-src->height)/2;
  73. cvZero(dst);
  74. for(int i=m.x,j=0;j<src->width;i++,j++){
  75. for(int k=m.y,n=0;n<src->height;k++,n++){
  76. cvSetReal2D(dst, k, i, cvGetReal2D(src, n, j));
  77. }
  78. }
  79. }
  80. //逻辑与操作
  81. int And(IplImage *src0,IplImage *src1,IplImage *dst){
  82. int isChanged=0;
  83. if(!isSIZEEQU(src0,src1)){
  84. printf("And wrong !\n");
  85. exit(0);
  86. }
  87. if(!isSIZEEQU(src0,dst)){
  88. printf("And wrong !\n");
  89. exit(0);
  90. }
  91. int width=src0->width;
  92. int height=src0->height;
  93. for(int i=0;i<width;i++){
  94. for(int j=0;j<height;j++){
  95. if(cvGetReal2D(src0, j, i)>100.0&&
  96. cvGetReal2D(src1, j, i)>100.0)
  97. cvSetReal2D(dst, j, i, 255.0);
  98. else
  99. cvSetReal2D(dst, j, i, 0.0);
  100. }
  101. }
  102. return isChanged;
  103. }
  104. //逻辑或操作
  105. void Or(IplImage *src0,IplImage *src1,IplImage *dst){
  106. if(!isSIZEEQU(src0,src1)){
  107. printf("And wrong !\n");
  108. exit(0);
  109. }
  110. if(!isSIZEEQU(src0,dst)){
  111. printf("And wrong !\n");
  112. exit(0);
  113. }
  114. int width=src0->width;
  115. int height=src0->height;
  116. for(int i=0;i<width;i++){
  117. for(int j=0;j<height;j++){
  118. if(cvGetReal2D(src0, j, i)>100.0||
  119. cvGetReal2D(src1, j, i)>100.0)
  120. cvSetReal2D(dst, j, i, 255);
  121. }
  122. }
  123. }
  124. //取反
  125. void Not(IplImage *src,IplImage *dst){
  126. if(!isSIZEEQU(src,dst)){
  127. printf("Not wrong !\n");
  128. exit(0);
  129. }
  130. int width=src->width;
  131. int height=src->height;
  132. for(int i=0;i<width;i++){
  133. for(int j=0;j<height;j++){
  134. cvSetReal2D(dst, j, i, 255.0-cvGetReal2D(src, j, i));
  135. }
  136. }
  137. }
  138. //将所有元素设为1
  139. void One(IplImage *src){
  140. for(int i=0;i<src->width;i++)
  141. for(int j=0;j<src->height;j++)
  142. cvSetReal2D(src, j, i, 255.0);
  143. }
  144. //膨胀
  145. void Dilate(IplImage *src,IplImage *dst,IplImage *se,Position *center){
  146. if(center==NULL){
  147. Position temp;
  148. temp.x=se->width/2;
  149. temp.y=se->height/2;
  150. center=&temp;
  151. }
  152. //printf("%d,%d",center->x,center->y);
  153. MoveDirection m;
  154. IplImage *temp=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  155. IplImage *tempdst=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  156. IplImage *realdst=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  157. cvZero(realdst);
  158. Zoom(src,temp);
  159. int width=se->width;
  160. int height=se->height;
  161. for(int i=0;i<width;i++){
  162. for(int j=0;j<height;j++){
  163. if(cvGetReal2D(se, j, i)>100.0){
  164. m.x=i-center->x;
  165. m.y=j-center->y;
  166. Translation(temp,tempdst, &m);
  167. Or(tempdst, realdst, realdst);
  168. }
  169. }
  170. }
  171. cvCopy(realdst, dst, NULL);
  172. cvReleaseImage(&temp);
  173. cvReleaseImage(&realdst);
  174. cvReleaseImage(&tempdst);
  175. }
  176. //腐蚀
  177. void Erode(IplImage *src,IplImage *dst,IplImage *se,Position *center){
  178. if(center==NULL){
  179. Position temp;
  180. temp.x=se->width/2;
  181. temp.y=se->height/2;
  182. center=&temp;
  183. }
  184. MoveDirection m;
  185. IplImage *temp=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  186. IplImage *tempdst=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  187. IplImage *realdst=cvCreateImage(cvGetSize(dst), dst->depth,dst->nChannels);
  188. One(realdst);
  189. Zoom(src,temp);
  190. int width=se->width;
  191. int height=se->height;
  192. for(int i=0;i<width;i++){
  193. for(int j=0;j<height;j++){
  194. if(cvGetReal2D(se, j, i)>100.0){
  195. m.x=center->x-i;
  196. m.y=center->y-j;
  197. Translation(temp,tempdst, &m);
  198. And(tempdst, realdst, realdst);
  199. }
  200. }
  201. }
  202. cvCopy(realdst, dst, NULL);
  203. cvReleaseImage(&tempdst);
  204. cvReleaseImage(&temp);
  205. cvReleaseImage(&realdst);
  206. }
  207. //开操作
  208. void Open(IplImage *src,IplImage *dst,IplImage *se,Position *center){
  209. Erode(src, dst, se, center);
  210. Dilate(dst, dst, se, center);
  211. }
  212. //关操作
  213. void Close(IplImage *src,IplImage *dst,IplImage *se,Position *center){
  214. Dilate(src, dst, se, center);
  215. Erode(dst, dst, se, center);
  216. }
  217. //击中与击不中
  218. void HitorMiss(IplImage *src,IplImage *se1,IplImage *se2,IplImage *dst,Position *se1center,Position *se2center){
  219. IplImage *temp1=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  220. IplImage *temp2=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  221. Erode(src, temp1, se1, se1center);
  222. Not(src, temp2);
  223. Erode(temp2, temp2, se2, se2center);
  224. And(temp1, temp2, dst);
  225. cvReleaseImage(&temp1);
  226. cvReleaseImage(&temp2);
  227. }
  228. //二值图像,边缘检测
  229. void BinaryEdge(IplImage *src,IplImage* dst){
  230. IplImage *temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  231. Erode(src, temp, NULL, NULL);
  232. cvSub(src, temp, dst, NULL);
  233. cvReleaseImage(&temp);
  234. }
  235. //孔洞填充
  236. void FillHole(IplImage *src,IplImage *dst,IplImage *se,Position *seed){
  237. IplImage * temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  238. cvZero(temp);
  239. IplImage * lasttemp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  240. IplImage * nsrc=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  241. Not(src, nsrc);
  242. cvSetReal2D(temp, seed->y, seed->x, 255.0);
  243. while(!isEqual(lasttemp, temp)){
  244. cvCopy(temp, lasttemp, NULL);
  245. Dilate(temp, temp, se, NULL);
  246. And(temp, nsrc, temp);
  247. }
  248. Or(temp, src, dst);
  249. cvReleaseImage(&temp);
  250. cvReleaseImage(&lasttemp);
  251. cvReleaseImage(&nsrc);
  252. }
  253. //连通分量获取
  254. void GetConComponent(IplImage *src,IplImage *dst,IplImage *se,Position *seed){
  255. IplImage * temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  256. cvZero(temp);
  257. IplImage * lasttemp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  258. cvSetReal2D(temp, seed->y, seed->x, 255.0);
  259. while(!isEqual(lasttemp, temp)){
  260. cvCopy(temp, lasttemp, NULL);
  261. Dilate(temp, temp, se, NULL);
  262. And(temp, src, temp);
  263. }
  264. cvCopy(temp, dst, NULL);
  265. cvReleaseImage(&temp);
  266. cvReleaseImage(&lasttemp);
  267. }
  268. //骨架
  269. void FrameWork(IplImage *src,IplImage *dst,IplImage *se){
  270. cvZero(dst);
  271. IplImage *temp=cvCreateImage(cvGetSize(src), src->depth,src->nChannels);
  272. IplImage *temp_open=cvCreateImage(cvGetSize(src), src->depth,src->nChannels);
  273. cvCopy(src, temp, NULL);
  274. while(!isEmpty(temp)){
  275. Erode(temp, temp, se, NULL);
  276. cvCopy(temp, temp_open, NULL);
  277. Open(temp_open, temp_open, se, NULL);
  278. cvSub(temp, temp_open, temp_open,NULL);
  279. Or(temp_open, dst, dst);
  280. }
  281. cvReleaseImage(&temp);
  282. cvReleaseImage(&temp_open);
  283. }
  284. //凸壳生成结构元
  285. IplImage* CreateConvexhullSE(int num){
  286. IplImage *se=cvCreateImage(cvSize(3, 3), 8, 1);
  287. cvZero(se);
  288. switch (num) {
  289. case 0:
  290. {
  291. cvSetReal2D(se, 0, 0, 255.0);
  292. cvSetReal2D(se, 1, 0, 255.0);
  293. cvSetReal2D(se, 2, 0, 255.0);
  294. }
  295. break;
  296. case 1:
  297. {
  298. cvSetReal2D(se, 0, 0, 255.0);
  299. cvSetReal2D(se, 0, 1, 255.0);
  300. cvSetReal2D(se, 0, 2, 255.0);
  301. }
  302. break;
  303. case 2:
  304. {
  305. cvSetReal2D(se, 0, 2, 255.0);
  306. cvSetReal2D(se, 1, 2, 255.0);
  307. cvSetReal2D(se, 2, 2, 255.0);
  308. }
  309. break;
  310. case 3:
  311. {
  312. cvSetReal2D(se, 2, 0, 255.0);
  313. cvSetReal2D(se, 2, 1, 255.0);
  314. cvSetReal2D(se, 2, 2, 255.0);
  315. }
  316. break;
  317. default:
  318. break;
  319. }
  320. return se;
  321. }
  322. //凸壳
  323. void Convexhull(IplImage *src,IplImage *dst){
  324. cvCopy(src, dst, NULL);
  325. IplImage * se[4];
  326. IplImage *temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  327. IplImage *temp_last=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  328. //cvCopy(src, temp, NULL);
  329. for(int i=0;i<4;i++){
  330. cvCopy(src, temp, NULL);
  331. se[i]=CreateConvexhullSE(i);
  332. while (!isEqual(temp, temp_last)) {
  333. cvCopy(temp, temp_last, NULL);
  334. Erode(temp, temp, se[i],NULL);
  335. Or(temp, dst, temp);
  336. }
  337. cvCopy(temp, dst, NULL);
  338. cvReleaseImage(&se[i]);
  339. }
  340. cvReleaseImage(&temp);
  341. cvReleaseImage(&temp_last);
  342. }
  343. //生成细化结构元
  344. IplImage* CreateThinningSE(int num){
  345. IplImage *se=cvCreateImage(cvSize(3, 3), 8, 1);
  346. cvZero(se);
  347. switch (num) {
  348. case 0:
  349. {
  350. cvSetReal2D(se, 2, 0, 255.0);
  351. cvSetReal2D(se, 2, 1, 255.0);
  352. cvSetReal2D(se, 2, 2, 255.0);
  353. cvSetReal2D(se, 1, 1, 255.0);
  354. }
  355. break;
  356. case 1:
  357. {
  358. cvSetReal2D(se, 1, 1, 255.0);
  359. cvSetReal2D(se, 1, 0, 255.0);
  360. cvSetReal2D(se, 2, 0, 255.0);
  361. cvSetReal2D(se, 2, 1, 255.0);
  362. }
  363. break;
  364. case 2:
  365. {
  366. cvSetReal2D(se, 1, 1, 255.0);
  367. cvSetReal2D(se, 1, 0, 255.0);
  368. cvSetReal2D(se, 2, 0, 255.0);
  369. cvSetReal2D(se, 0, 0, 255.0);
  370. }
  371. break;
  372. case 3:
  373. {
  374. cvSetReal2D(se, 1, 1, 255.0);
  375. cvSetReal2D(se, 0, 0, 255.0);
  376. cvSetReal2D(se, 0, 1, 255.0);
  377. cvSetReal2D(se, 1, 0, 255.0);
  378. }
  379. break;
  380. case 4:
  381. {
  382. cvSetReal2D(se, 1, 1, 255.0);
  383. cvSetReal2D(se, 0, 0, 255.0);
  384. cvSetReal2D(se, 0, 1, 255.0);
  385. cvSetReal2D(se, 0, 2, 255.0);
  386. }
  387. break;
  388. case 5:
  389. {
  390. cvSetReal2D(se, 0, 1, 255.0);
  391. cvSetReal2D(se, 0, 2, 255.0);
  392. cvSetReal2D(se, 1, 1, 255.0);
  393. cvSetReal2D(se, 1, 2, 255.0);
  394. }
  395. break;
  396. case 6:
  397. {
  398. cvSetReal2D(se, 1, 1, 255.0);
  399. cvSetReal2D(se, 0, 2, 255.0);
  400. cvSetReal2D(se, 1, 2, 255.0);
  401. cvSetReal2D(se, 2, 2, 255.0);
  402. }
  403. break;
  404. case 7:
  405. {
  406. cvSetReal2D(se, 1, 1, 255.0);
  407. cvSetReal2D(se, 1, 2, 255.0);
  408. cvSetReal2D(se, 2, 1, 255.0);
  409. cvSetReal2D(se, 2, 2, 255.0);
  410. }
  411. break;
  412. default:
  413. break;
  414. }
  415. return se;
  416. }
  417. IplImage* CreateThinningUSE(int num){
  418. IplImage *se=cvCreateImage(cvSize(3, 3), 8, 1);
  419. cvZero(se);
  420. switch (num) {
  421. case 0:
  422. {
  423. cvSetReal2D(se, 0, 1, 255.0);
  424. cvSetReal2D(se, 0, 2, 255.0);
  425. cvSetReal2D(se, 0, 0, 255.0);
  426. }
  427. break;
  428. case 1:
  429. {
  430. cvSetReal2D(se, 0, 1, 255.0);
  431. cvSetReal2D(se, 0, 2, 255.0);
  432. cvSetReal2D(se, 1, 2, 255.0);
  433. }
  434. break;
  435. case 2:
  436. {
  437. cvSetReal2D(se, 0, 2, 255.0);
  438. cvSetReal2D(se, 1, 2, 255.0);
  439. cvSetReal2D(se, 2, 2, 255.0);
  440. }
  441. break;
  442. case 3:
  443. {
  444. cvSetReal2D(se, 1, 2, 255.0);
  445. cvSetReal2D(se, 2, 1, 255.0);
  446. cvSetReal2D(se, 2, 2, 255.0);
  447. }
  448. break;
  449. case 4:
  450. {
  451. cvSetReal2D(se, 2, 0, 255.0);
  452. cvSetReal2D(se, 2, 1, 255.0);
  453. cvSetReal2D(se, 2, 2, 255.0);
  454. }
  455. break;
  456. case 5:
  457. {
  458. cvSetReal2D(se, 1, 0, 255.0);
  459. cvSetReal2D(se, 2, 0, 255.0);
  460. cvSetReal2D(se, 2, 1, 255.0);
  461. }
  462. break;
  463. case 6:
  464. {
  465. cvSetReal2D(se, 0, 0, 255.0);
  466. cvSetReal2D(se, 1, 0, 255.0);
  467. cvSetReal2D(se, 2, 0, 255.0);
  468. }
  469. break;
  470. case 7:
  471. {
  472. cvSetReal2D(se, 0, 0, 255.0);
  473. cvSetReal2D(se, 0, 1, 255.0);
  474. cvSetReal2D(se, 1, 0, 255.0);
  475. }
  476. break;
  477. default:
  478. break;
  479. }
  480. return se;
  481. }
  482. //细化操作
  483. void Thinning(IplImage *src,IplImage *dst){
  484. IplImage *temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  485. IplImage *temp_last=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  486. IplImage *temp_com=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  487. cvZero(temp_last);
  488. cvCopy(src, temp, NULL);
  489. while(!isEqual(temp, temp_com)){
  490. cvCopy(temp, temp_com, NULL);
  491. for(int i=0;i<8;i++){
  492. cvCopy(temp, temp_last, NULL);
  493. IplImage *se1=CreateThinningSE(i);
  494. IplImage *se2=CreateThinningUSE(i);
  495. HitorMiss(temp, se1, se2, temp, NULL, NULL);
  496. cvSub(temp_last, temp, temp, NULL);
  497. cvReleaseImage(&se1);
  498. cvReleaseImage(&se2);
  499. }
  500. }
  501. cvCopy(temp, dst, NULL);
  502. cvReleaseImage(&temp);
  503. cvReleaseImage(&temp_com);
  504. cvReleaseImage(&temp_last);
  505. }
  506. //重建开操作
  507. void reBuildOpen(IplImage *src,IplImage *dst,IplImage *ground,IplImage *dilateSE,IplImage *erodeSE,int eroden){
  508. IplImage *temp=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  509. IplImage *temp_last=cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  510. cvCopy(src, temp, NULL);
  511. for(int i=0;i<eroden;i++){
  512. Erode(temp, temp, erodeSE, NULL);
  513. }
  514. while(!isEqual(temp, temp_last)){
  515. cvCopy(temp, temp_last, NULL);
  516. Dilate(temp, temp, dilateSE, NULL);
  517. And(temp, ground, temp);
  518. }
  519. cvCopy(temp, dst, NULL);
  520. cvReleaseImage(&temp);
  521. cvReleaseImage(&temp_last);
  522. }
  523. int main(){
  524. return 0;
  525. }
时间: 2024-10-27 04:02:59

形态学处理函数的相关文章

【计算机视觉】形态学滤波

[计算机视觉]形态学滤波 标签(空格分隔): [图像处理] [信号处理] 版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/lg1259156776/. 说明:本文主要想弄清楚形态学滤波在图象处理和信号处理中的应用,图像处理中非常直观的通过腐蚀膨胀获得开闭运算的效果,而在数据实时滤波中,形态学滤波也是可以使用的. 形态学滤波基本知识 原理:在特殊领域运算形式--结构元素(Sturcture Element),在每个像素位置上与二值图像对应的区域进行特定的逻辑运

OpenCV2马拉松第16圈——边缘检测(形态学梯度)

计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g 收入囊中 利用OpenCV函数进行形态学梯度操作 自定义结构矩阵进行形态学梯度操作 葵花宝典 在此之前,如果你还没接触过灰度图像形态学膨胀与腐蚀,希望你能仔细阅读灰度图像形态学膨胀与腐蚀 本质上,灰度与二值并不差异,二值不过是0与255,膨胀与腐蚀的操作都是一样的 形态学梯度的定义如下: 形态梯度 dst=morph_grad(src,element)=dilate(src,ele

Matlab图像处理基本函数(1)

表13   灰度形态学(或二值图像)处理函数 函数                       说明 conndef               创建连通矩阵 imbothat              执行bottom-hat滤波 imclearborder         抑制边缘亮结构 imclose               灰度图像或二值图像的闭运算 imdilate              灰度图像或二值图像的膨胀运算 imerode               灰度图像或二值图

opencv2函数学习之erode、dilate:图像腐蚀和膨胀

图像腐蚀和图像膨胀是图像中两种最基本形态学操作. void erode( const Mat& src, Mat& dst, const Mat& element,Point anchor=Point(-1,-1), int iterations=1,int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ); void dilate( const Ma

学习 opencv---(10)形态学图像处理(2):开运算,闭运算,形态学梯度,顶帽,黒帽合辑

上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换. 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算.形态学梯度."顶帽"."黑帽"等等. 第二件事,是浅墨想跟大家做一个关于OpenCV系列文章的书写内容和风格的思想汇报. 是这样的,浅墨发现最近几期写出来的文章有些偏离自己开始开这个专栏的最初的愿望--原理和概念部分占的

OpenCV2学习笔记(三):形态学及边缘角点检测

形态学滤波理论于上世纪90年代提出,目前被广泛用于分析及处理离散图像.其基本运算有4个: 膨胀.腐蚀.开启和闭合, 它们在二值图像和灰度图像中各有特点.基于这些基本运算还可推导和组合成各种数学形态学实用算法,用它们可以进行图像形状和结构的分析及处理,包括图像分割.特征抽取.边缘检测. 图像滤波.图像增强和恢复等.数学形态学方法利用一个称作结构元素的"探针"收集图像的信息,当探针在图像中不断移动时, 便可考察图像各个部分之间的相互关系,从而了解图像的结构特征.数学形态学基于探测的思想,与

形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽

一.开运算 开运算,就是先腐蚀后膨胀的过程 数学表达式: dst = open(src,element) = dilate(erode(src, element)) 开运算可以用来消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积. 二.闭运算 闭运算,就是先膨胀后腐蚀的过程 数学表达式: dst = open(src,element) = erode(dilate(src, element)) 闭运算可以用来排除小型黑洞(黑色区域) 三.形态学梯度 形态学梯度,就是

学习 opencv---(9)形态学图像处理(一):膨胀和腐蚀

本篇文章中,我们一起探究了图像处理中,最基本的形态学运算--膨胀与腐蚀.浅墨在文章开头友情提醒,用人物照片做腐蚀和膨胀的素材图片得到的效果会比较惊悚,毁三观的,不建议尝试.......... 一.理论与概念讲解--从现象到本质 1.1 形态学概述 形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构,而我们图像处理中指的形态学,往往表示的是数学形态学,下面一起来了解数学形态学的概念. 数学形态学(Mathematical morphology)是一门建立在

常用的OpenCV函数速查

常用的OpenCV函数速查 1.cvLoadImage:将图像文件加载至内存: 2.cvNamedWindow:在屏幕上创建一个窗口: 3.cvShowImage:在一个已创建好的窗口中显示图像: 4.cvWaitKey:使程序暂停,等待用户触发一个按键操作: 5.cvReleaseImage:释放图像文件所分配的内存: 6.cvDestroyWindow:销毁显示图像文件的窗口: 7.cvCreateFileCapture:通过参数设置确定要读入的AVI文件: 8.cvQueryFrame:用