日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算联通区域

發(fā)布時間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算联通区域 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

對于這樣的圖片:

摳出其中的黑色區(qū)域,效果如下:

import cv2 import numpy as np import matplotlib.pyplot as plt import timedef findUnicomArea(img):#先二值化ret,threshold = cv2.threshold(img,128,255,cv2.THRESH_BINARY)img_flag = np.zeros(threshold.shape,np.int8)count = 0findpoint = []#首先遍歷圖像找到所有的聯(lián)通區(qū)for x in range(threshold.shape[0]):for y in range(threshold.shape[1]):if(threshold[x][y] == 0 and img_flag[x][y] == 0):#這里表示已經(jīng)找到了一個沒有標志過的黑點,是一個新的聯(lián)通區(qū)count += 1img_flag[x][y] = countfindpoint.append((x,y))while len(findpoint) > 0:xx,yy = findpoint.pop()if xx > 0 :#上面if threshold[xx-1][yy] == 0 and img_flag[xx-1][yy] == 0:findpoint.append((xx-1,yy))img_flag[xx-1][yy] = countif xx < img.shape[0]:#下面if threshold[xx + 1][yy] == 0 and img_flag[xx + 1][yy] == 0:findpoint.append((xx + 1, yy))img_flag[xx+1][yy] = countif yy > 0:#左面if threshold[xx][yy-1] == 0 and img_flag[xx][yy-1] == 0:findpoint.append((xx, yy-1))img_flag[xx][yy-1] = countif yy < img.shape[1]:#右面if threshold[xx][yy+1] == 0 and img_flag[xx][yy+1] == 0:findpoint.append((xx, yy+1))img_flag[xx][yy+1] = count#聯(lián)通區(qū)任然存在一張表中,需要將其分離coutours = []for num in range(1,count+1):coutours.append([])for x in range(img_flag.shape[0]):for y in range(img_flag.shape[1]):if img_flag[x][y] == num:coutours[num-1].append([x,y,img_flag[x][y]])desCoutous = np.empty(len(coutours),np.object)for num in range(len(coutours)):#將分離后的圖像提取出來。計算出聯(lián)通區(qū)所在的范圍tmp = np.mat(coutours[num])minX = np.min(tmp[:,0])maxX = np.max(tmp[:,0])minY = np.min(tmp[:,1])maxY = np.max(tmp[:,1])desCoutous[num] = img[minX:maxX,minY:maxY]return desCoutous#測試程序如下 img = cv2.imread("testpic/connected_test.png",0); cost = time.time() unicoms = findUnicomArea(img) print("cost",time.time()-cost) for i in range(len(unicoms)):cv2.imshow("test"+str(i),unicoms[i])cv2.waitKey(0)

目前只是實現(xiàn)了功能,效率還不高,還有很大的優(yōu)化空間。

這個程序顯然有重復計算,第二次循環(huán)完全可以略去,可以合并到第一個循環(huán)中。另外,只需要遍歷1~shape[0]-1的空間就能找到所有的點,所以邊界的比較也可以省去,如此,程序如下:

def findUnicomArea(img):#先二值化ret,threshold = cv2.threshold(img,128,255,cv2.THRESH_BINARY)img_flag = np.zeros(threshold.shape,np.int8)count = 0findpoint = []coutours = []#首先遍歷圖像找到所有的聯(lián)通區(qū)for x in range(1,threshold.shape[0]-1):for y in range(1,threshold.shape[1]-1):if(threshold[x][y] == 0 and img_flag[x][y] == 0):#這里表示已經(jīng)找到了一個沒有標志過的黑點,是一個新的聯(lián)通區(qū)count += 1#新增一個聯(lián)通區(qū)存儲點coutours.append([])img_flag[x][y] = countfindpoint.append((x,y))while len(findpoint) > 0:xx,yy = findpoint.pop()#上面if threshold[xx-1][yy] == 0 and img_flag[xx-1][yy] == 0:findpoint.append((xx-1,yy))img_flag[xx-1][yy] = countcoutours[count - 1].append([xx, yy, img_flag[x][y]])#下面if threshold[xx + 1][yy] == 0 and img_flag[xx + 1][yy] == 0:findpoint.append((xx + 1, yy))img_flag[xx+1][yy] = countcoutours[count - 1].append([xx, yy, img_flag[x][y]])#左面if threshold[xx][yy-1] == 0 and img_flag[xx][yy-1] == 0:findpoint.append((xx, yy-1))img_flag[xx][yy-1] = countcoutours[count - 1].append([xx, yy, img_flag[x][y]])#右面if threshold[xx][yy+1] == 0 and img_flag[xx][yy+1] == 0:findpoint.append((xx, yy+1))img_flag[xx][yy+1] = countcoutours[count - 1].append([xx, yy, img_flag[x][y]])desCoutous = np.empty(len(coutours),np.object)for num in range(len(coutours)):#將分離后的圖像提取出來。計算出聯(lián)通區(qū)所在的范圍tmp = np.mat(coutours[num])minX = np.min(tmp[:,0])maxX = np.max(tmp[:,0])minY = np.min(tmp[:,1])maxY = np.max(tmp[:,1])desCoutous[num] = img[minX:maxX,minY:maxY]return desCoutous

這樣程序性能從1.3秒提升至0.8秒,程序有了顯著的提升。
如果我們只是摳出圖中的聯(lián)通區(qū)的話,只需要檢測邊界聯(lián)通區(qū)的外邊界就可以了,這樣效率能進一步提升。

def findUnicomBoundry(img):#先二值化ret,threshold = cv2.threshold(img,128,255,cv2.THRESH_BINARY)img_flag = np.zeros(threshold.shape,np.int8)count = 0findpoint = []coutours = []desCoutous = []existCoutous = []#首先遍歷圖像找到所有的聯(lián)通區(qū)for x in range(1,threshold.shape[0]-1):for y in range(1,threshold.shape[1]-1):if(threshold[x][y] == 0 and (threshold[x-1][y]==255 or threshold[x+1][y]==255 or threshold[x][y-1]==255 or threshold[x][y+1]==255) and img_flag[x][y] == 0):#是邊界的條件是中心點為0,四周至少要有一個白點#這里表示已經(jīng)找到了一個邊界點,并且是一個新的聯(lián)通區(qū)的邊界點# 將分離后的圖像提取出來。計算出聯(lián)通區(qū)所在的范圍if count > len(desCoutous):desCoutous.append([])tmp = np.mat(coutours[count - 1])minX = np.min(tmp[:, 0])maxX = np.max(tmp[:, 0])minY = np.min(tmp[:, 1])maxY = np.max(tmp[:, 1])existCoutous.append([minX, maxX, minY, maxY])desCoutous[count - 1] = img[minX:maxX, minY:maxY]desCoutous[count-1] = np.mat(desCoutous[count-1])isChildArea = Falsefor num in range(len(existCoutous)):if x>existCoutous[num][0] and x < existCoutous[num][1] and y > existCoutous[num][2] and y < existCoutous[num][3] :isChildArea = Trueif not isChildArea:count += 1#新增一個聯(lián)通區(qū)的邊界存儲點coutours.append([])img_flag[x][y] = countfindpoint.append((x,y))while len(findpoint) > 0:#xx,yy肯定是一個邊界點了,現(xiàn)在尋找下一個邊界點xx,yy = findpoint.pop()#上面if threshold[xx-1][yy] == 0 and (threshold[xx-2][yy]==255 or threshold[xx-1][yy-1]==255 or threshold[xx-1][yy+1]==255) and img_flag[xx-1][yy] == 0:findpoint.append((xx-1,yy))img_flag[xx-1][yy] = countcoutours[count - 1].append([xx-1, yy, img_flag[xx-1][yy]])#下面if threshold[xx + 1][yy] == 0 and (threshold[xx+1][yy]==255 or threshold[xx+1][yy-1]==255 or threshold[xx+1][yy+1]==255) and img_flag[xx + 1][yy] == 0:findpoint.append((xx + 1, yy))img_flag[xx+1][yy] = countcoutours[count - 1].append([xx+1, yy, img_flag[xx][yy]])#左面if threshold[xx][yy-1] == 0 and (threshold[xx][yy-2]==255 or threshold[xx-1][yy-1]==255 or threshold[xx+1][yy-1]==255) and img_flag[xx][yy-1] == 0:findpoint.append((xx, yy-1))img_flag[xx][yy-1] = countcoutours[count - 1].append([xx, yy-1, img_flag[xx][yy-1]])#右面if threshold[xx][yy+1] == 0 and (threshold[xx][yy+2]==255 or threshold[xx-1][yy+1]==255 or threshold[xx+1][yy+1]==255) and img_flag[xx][yy+1] == 0:findpoint.append((xx, yy+1))img_flag[xx][yy+1] = countcoutours[count - 1].append([xx, yy+1, img_flag[xx][yy+1]])#左上if threshold[xx-1][yy-1] == 0 and (threshold[xx-2][yy-1]==255 or threshold[xx][yy]==255 or threshold[xx-1][yy-2]==255 or threshold[xx-1][yy]==255) and img_flag[xx-1][yy-1] == 0:findpoint.append((xx-1, yy-1))img_flag[xx-1][yy-1] = countcoutours[count - 1].append([xx-1, yy-1, img_flag[xx-1][yy-1]])#右上if threshold[xx-1][yy+1] == 0 and (threshold[xx-2][yy+1]==255 or threshold[xx][yy+1]==255 or threshold[xx-1][yy]==255 or threshold[xx-1][yy+1]==255) and img_flag[xx-1][yy+1] == 0:findpoint.append((xx-1, yy+1))img_flag[xx-1][yy+1] = countcoutours[count - 1].append([xx-1, yy+1, img_flag[xx-1][yy+1]])#左下if threshold[xx+1][yy-1] == 0 and (threshold[xx][yy-1]==255 or threshold[xx+2][yy-1]==255 or threshold[xx+1][yy-2]==255 or threshold[xx+1][yy]==255) and img_flag[xx+1][yy-1] == 0:findpoint.append((xx+1, yy-1))img_flag[xx+1][yy-1] = countcoutours[count - 1].append([xx+1, yy-1, img_flag[xx+1][yy-1]])#右下if threshold[xx+1][yy+1] == 0 and (threshold[xx][yy+1]==255 or threshold[xx+2][yy+1]==255 or threshold[xx+1][yy]==255 or threshold[xx+1][yy+2]==255) and img_flag[xx+1][yy+1] == 0:findpoint.append((xx+1, yy+1))img_flag[xx+1][yy+1] = countcoutours[count - 1].append([xx+1, yy+1, img_flag[xx+1][yy+1]])return desCoutous

程序的運行時間縮小到0.6秒

c++基于opencv的實現(xiàn):

#include<opencv2/opencv.hpp> #include<iostream> using namespace std; using namespace cv;Mat findContinousArea(Mat& img) {int rows = img.rows;int cols = img.cols;Mat coutinous = Mat(img.rows,img.cols,img.type(),Scalar(0));queue<Point> tmp;int cCount = 0;for(int i=0;i<rows;i++){for(int j=0;j<cols;j++){if(img.at<char>(i,j)==0 && coutinous.at<char>(i,j)==0){cCount+=30;tmp.push(Point(i,j));coutinous.at<char>(i,j) = cCount;while(!tmp.empty()){Point p = tmp.front();tmp.pop();if(p.x>0 && img.at<char>(p.x-1,p.y)==0 && coutinous.at<char>(p.x-1,p.y)==0){tmp.push(Point(p.x-1,p.y));coutinous.at<char>(p.x-1,p.y) = cCount;}if(p.x<rows && img.at<char>(p.x+1,p.y)==0 && coutinous.at<char>(p.x+1,p.y)==0){tmp.push(Point(p.x+1,p.y));coutinous.at<char>(p.x+1,p.y) = cCount;}if(p.y>0 && img.at<char>(p.x,p.y-1)==0 && coutinous.at<char>(p.x,p.y-1)==0){tmp.push(Point(p.x,p.y-1));coutinous.at<char>(p.x,p.y-1) = cCount;}if(p.y<cols && img.at<char>(p.x,p.y+1)==0 && coutinous.at<char>(p.x,p.y+1)==0){tmp.push(Point(p.x,p.y+1));coutinous.at<char>(p.x,p.y+1) = cCount;}}}}}return coutinous; }int main() {Mat frame = imread("/Users/jinweiliu/Pictures/coutinous.png",0);int rows = frame.rows;int cols = frame.cols;//二值化for(int i=0;i<rows;i++){for(int j=0;j<cols;j++){if((frame.at<char>(i,j)&0xff)<128){frame.at<char>(i,j) = 0;}else{frame.at<char>(i,j) = (char)255;}}}TickMeter tm;tm.start();Mat coutinous = findContinousArea(frame);tm.stop();cout<<tm.getTimeMilli()<<endl;imshow("test",coutinous);waitKey();return 0; }

原圖:

結果如下:

注意,結果是用不同的數(shù)字表示不同的聯(lián)通區(qū)的,比如,第一個聯(lián)通區(qū)全部標志為30,第二個全部標志為60,以此類推。之所以是30,60,90等而不是1,2,3等是因為顯示出來看著比較明顯。這里只是把不同的聯(lián)通區(qū)標示出來,并沒有做切割之類的,僅供參考。最后,c++的這段代碼耗時只有3ms,性能還是挺不錯的。

總結

以上是生活随笔為你收集整理的计算联通区域的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品视频麻豆 | 天天操免费视频 | 大胸美女网站 | www.久草.com| 久久久久一区二区精码av少妇 | 久久四虎| 天堂av网站| 免费观看一级黄色片 | 女人扒开屁股让男人桶 | 台湾a级艳片潘金莲 | 欧美gv在线观看 | 久久久久久久爱 | 欧美激情免费 | 秋霞免费av | 热久久91 | 另类综合网 | 国产精品久久99 | 涩涩视频网站在线观看 | 黄色一级二级 | 日本少妇高潮 | 亚洲天堂第一 | 农村激情伦hxvideos | xxx视频网站 | 亚洲免费视频一区二区三区 | 亚洲熟女乱色综合亚洲小说 | 俺去日 | 中文毛片无遮挡高潮免费 | 国产在线精品一区 | 国产+日韩+欧美 | 成人黄色免费看 | 日韩精品视频久久 | 国产一线二线三线女 | www奇米影视com| 少妇高潮av久久久久久 | 朱竹清到爽高潮痉挛 | 波多野结衣之双调教hd | va在线 | 超碰黄色| 精品日本一区二区三区 | 蜜臀久久99精品久久久久久 | 黄色小视频免费观看 | 国内精品久久久久久久久久久 | 久久小草 | 国产自产在线视频 | 亚洲综合视频在线观看 | 青青草原成人 | 毛片在线视频观看 | 殴美一区二区 | 日韩高清免费av | 亚洲一级黄色 | 中文字幕免费看 | 亚洲情侣av| 特黄一区二区三区 | 中文字幕日韩一区 | 国产一二三四在线 | 中文字幕乱码人妻无码久久95 | 日韩免费福利视频 | 朝桐光av在线 | 69av导航| 精品女厕偷拍一区二区 | 欧美高潮视频 | 久久免费精品视频 | 蜜臀aⅴ国产精品久久久国产老师 | 日本免费高清一区二区 | 国产区一区二区 | 欧美巨乳在线观看 | 一区久久久 | 日本香蕉视频 | 精品在线第一页 | 四虎综合网 | 日本男男激情gay办公室 | 国产亚洲欧美日韩高清 | 深夜国产视频 | 在线黄色大片 | 成人免费毛片网站 | 亚洲激情视频在线 | 国产不卡视频 | 久久精品欧美日韩精品 | 在线免费看污片 | 成人欧美一区 | 日本久久网 | 久久网站免费观看 | 在线看片网址 | 成人短视频在线观看 | 国产成人精品二区三区亚瑟 | 久久日本视频 | 尤物在线视频 | 人妻少妇无码精品视频区 | 国产精品传媒一区二区 | 无码视频一区二区三区 | 青青草国产一区二区三区 | 国产精品36p | 黑丝久久 | 99re这里只有精品在线观看 | 国产在线不卡av | 123超碰 | 国产人妻精品一区二区三区不卡 | 波多野结衣电影免费观看 | 91成人精品国产刺激国语对白 |