├── README.md ├── Seg2.cpp ├── data.jpg ├── hist_seg.cpp ├── hist_seg.png ├── imgcmp.cpp ├── kmeans.cpp ├── kmeans.png ├── otsu.cpp ├── otsu.png ├── seg.cpp ├── seg.png ├── seg2.png ├── seg4.cpp └── seg4.png /README.md: -------------------------------------------------------------------------------- 1 | # Image-Segmentation 2 | 3 | Contains C++ codes for image segmentation i.e. dividing image into segments which are similar. 4 | 5 | Libraries used are openCV(for reading and saving image) and openMP(for parallelizing the program) 6 | 7 | Contents are- 8 | 9 | 1. seg.cpp- Parallel implementation of Boruvka's algorithm for image segmentation (Faster). 10 | 11 | 2. seg2.cpp- Serialized implementation of Boruvka's algorithm for image segmentation (Better Results for most images). 12 | 13 | 3. seg4.cpp- Parallel implementation of Boruvka's algorithm for image segmentation (much slower due to locks). 14 | 15 | 4. hist_seg.cpp- Parallel implementation of histogram thresholding method for image segmentation. 16 | 17 | 5. imgcmp.cpp- A program to compare two images. The output is a completely black image if the images are similar else at each point of difference there will be white color. 18 | 19 | 6. otsu.cpp- Serialized implementation of Otsu's method for image segmentation. 20 | 21 | 7. kmeans.cpp- Serialized implementation of K-means clustering algorithm for image segmentation. 22 | -------------------------------------------------------------------------------- /Seg2.cpp: -------------------------------------------------------------------------------- 1 | //Serialized implementation for image segmentation using Boruvka's algorithm 2 | 3 | #include 4 | #include 5 | #include 6 | #include "opencv2/highgui/highgui.hpp" 7 | #include 8 | using namespace std; 9 | using namespace cv; 10 | struct pixel{ 11 | int x; 12 | int y; 13 | }; 14 | bool use=false; 15 | typedef struct un un; 16 | typedef struct pixel pixel; 17 | struct edge{ 18 | float weigh; 19 | pixel node1; 20 | pixel node2; 21 | }; 22 | typedef struct edge edge; 23 | float weight(int p1[],int p2[]) 24 | { 25 | float weight=(p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]); 26 | weight=sqrt(weight); 27 | return weight; 28 | } 29 | int root (vector &Arr ,int i) 30 | { 31 | 32 | while(Arr[i]!= i) 33 | { 34 | Arr[i] = Arr[Arr[i]] ; 35 | i = Arr[i]; 36 | } 37 | return i; 38 | } 39 | int main() 40 | { 41 | Mat img1; 42 | float k=30; 43 | string name="data.jpg"; 44 | 45 | img1=imread(name); 46 | //resize(img1,img1,cvSize(1920,1080)); 47 | int x=img1.rows; 48 | int y=img1.cols; 49 | cout< edges; 52 | vector Array(x*y); 53 | vector Size(x*y); 54 | vector cheapest(x*y); 55 | vector Earray(x*y); 56 | int chunk=(y)/16; 57 | 58 | for(int i=0;i(i,j)[0]; 70 | t1[1]=img1.at(i,j)[1]; 71 | t1[2]=img1.at(i,j)[2]; 72 | t2[0]=img1.at(i+1,j)[0]; 73 | t2[1]=img1.at(i+1,j)[1]; 74 | t2[2]=img1.at(i+1,j)[2]; 75 | edge e1; 76 | e1.weigh=weight(t1,t2); 77 | e1.node1.x=i; 78 | e1.node1.y=j; 79 | e1.node2.x=i+1; 80 | e1.node2.y=j; 81 | edges.push_back(e1); 82 | } 83 | else if(i==x-1) 84 | { 85 | int t1[3]; 86 | int t2[3]; 87 | t1[0]=img1.at(i,j)[0]; 88 | t1[1]=img1.at(i,j)[1]; 89 | t1[2]=img1.at(i,j)[2]; 90 | t2[0]=img1.at(i,j+1)[0]; 91 | t2[1]=img1.at(i,j+1)[1]; 92 | t2[2]=img1.at(i,j+1)[2]; 93 | edge e1; 94 | e1.weigh=weight(t1,t2); 95 | e1.node1.x=i; 96 | e1.node1.y=j; 97 | e1.node2.x=i; 98 | e1.node2.y=j+1; 99 | edges.push_back(e1); 100 | } 101 | else{ 102 | int t1[3]; 103 | int t2[3]; 104 | t1[0]=img1.at(i,j)[0]; 105 | t1[1]=img1.at(i,j)[1]; 106 | t1[2]=img1.at(i,j)[2]; 107 | t2[0]=img1.at(i+1,j)[0]; 108 | t2[1]=img1.at(i+1,j)[1]; 109 | t2[2]=img1.at(i+1,j)[2]; 110 | edge e1; 111 | e1.weigh=weight(t1,t2); 112 | e1.node1.x=i; 113 | e1.node1.y=j; 114 | e1.node2.x=i+1; 115 | e1.node2.y=j; 116 | // cout<<(2*(i*y+j))-i; 117 | edges.push_back(e1); 118 | t2[0]=img1.at(i,j+1)[0]; 119 | t2[1]=img1.at(i,j+1)[1]; 120 | t2[2]=img1.at(i,j+1)[2]; 121 | e1.weigh=weight(t1,t2); 122 | e1.node2.x=i; 123 | e1.node2.y=j+1; 124 | edges.push_back(e1); 125 | //cout<<"e"; 126 | } 127 | } 128 | } 129 | double time=omp_get_wtime(); 130 | #pragma omp for schedule(dynamic,x*y/30) 131 | for(int i=0;iedges[i].weigh) 167 | { 168 | //#pragma omp atomic write 169 | //#pragma omp critical 170 | cheapest[ra]=i; 171 | //omp_unset_lock(&locks[ra]); 172 | } 173 | if(cheapest[rc]==-1 || edges[cheapest[rc]].weigh>edges[i].weigh) 174 | { 175 | //#pragma omp critical 176 | //#pragma omp atomic write 177 | //#pragma omp critical 178 | cheapest[rc]=i; 179 | //omp_unset_lock(&locks[rc]); 180 | } 181 | } 182 | } 183 | temp=0; 184 | //#pragma omp parallel for schedule(dynamic,x*y/8) reduction(+:temp) 185 | //#pragma omp master 186 | 187 | for(int i=0;iT2?T2:T1; 222 | //condition for merging the two trees 223 | if (b.weigh<=min) 224 | { 225 | //union 226 | if(Size[ra]>Size[rb]) 227 | { 228 | Size[ra]+=Size[rb]; 229 | Array[rb]=ra; 230 | if(edges[cheapest[i]].weigh>Earray[ra]) 231 | Earray[ra]=edges[cheapest[i]].weigh; 232 | if (Earray[ra]<=Earray[rb]) 233 | Earray[ra]=Earray[rb]; 234 | cheapest[ra]=-1; 235 | //cout<<"df"; 236 | } 237 | else 238 | { 239 | Size[rb]+=Size[ra]; 240 | Array[ra]=rb; 241 | if(edges[cheapest[i]].weigh>Earray[rb]) 242 | Earray[rb]=edges[cheapest[i]].weigh; 243 | if (Earray[rb]<=Earray[ra]) 244 | Earray[rb]=Earray[ra]; 245 | cheapest[rb]=-1; 246 | } 247 | temp++; 248 | } 249 | // omp_unset_lock(&locks[a]); 250 | // omp_unset_lock(&locks[c]); 251 | } 252 | } 253 | counter-=temp; 254 | if(t==counter) 255 | flag=1; 256 | } 257 | #pragma omp parallel for schedule(dynamic,chunk) 258 | for(int i=0;i(xcoord,ycoord)[0]=img1.at(rcx,rcy)[0]; 266 | img1.at(xcoord,ycoord)[2]=img1.at(rcx,rcy)[2]; 267 | img1.at(xcoord,ycoord)[1]=img1.at(rcx,rcy)[1]; 268 | // if(rc==root(Array,0)) 269 | // { 270 | // img1.at(xcoord,ycoord)[0]=0; 271 | // img1.at(xcoord,ycoord)[2]=0; 272 | // img1.at(xcoord,ycoord)[1]=0; 273 | // } 274 | } 275 | time=omp_get_wtime()-time; 276 | cout< 2 | #include 3 | #include 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include 6 | #include 7 | #define THRESHOLD 20 8 | using namespace std; 9 | using namespace cv; 10 | typedef struct centroid 11 | { 12 | int r,g,b,counter; 13 | }centroid; 14 | /*Smoothen the histogram by making the value equal to 15 | the mean of all the values in a window of size 5*/ 16 | void smoothen(int histogram[],int mhistogram[]) 17 | { 18 | for(int i=0;i<2;i++) 19 | { 20 | mhistogram[i]=histogram[i]; 21 | mhistogram[255-i]=histogram[255-i]; 22 | } 23 | for(int i=2;i<254;i++) 24 | { 25 | mhistogram[i]=(histogram[i-2]+histogram[i-1]+histogram[i]+histogram[i+1]+histogram[i+2])/5; 26 | } 27 | } 28 | /*Calculate the distance of pixel from the centroid*/ 29 | float distance(int r,int g,int b,centroid cent) 30 | { 31 | return sqrt(float((r-cent.r)*(r-cent.r)+(g-cent.g)*(g-cent.g)+(b-cent.b)*(b-cent.b))); 32 | } 33 | /*Return the indexes of the peaks in the histogram*/ 34 | vector peak_finder(int histogram[],int x,int y) 35 | { 36 | vector peaks; 37 | if(histogram[0]>histogram[1]) 38 | peaks.push_back(0); 39 | for(int i=1;i<255;i++) 40 | { 41 | if(histogram[i]>histogram[i-1] && histogram[i]>histogram[i+1]) 42 | { 43 | if(histogram[i]>(x*y)/400) 44 | peaks.push_back(i); 45 | } 46 | } 47 | if(histogram[254] centroid_finder(vector &rpeaks,vector &gpeaks,vector &bpeaks) 54 | { 55 | int rs=rpeaks.size(); 56 | int bs=bpeaks.size(); 57 | int gs=gpeaks.size(); 58 | vector centroids; 59 | for(int i=0;i ¢roids,Mat &image,vector &parents) 81 | { 82 | int size=centroids.size(); 83 | int x=image.rows; 84 | int y=image.cols; 85 | #pragma omp parallel for schedule(dynamic,x/20) 86 | for(int i=0;i(i,j)[2]; 95 | int g=image.at(i,j)[1]; 96 | int b=image.at(i,j)[0]; 97 | float dist=distance(r,g,b,centroids[k]); 98 | if(k==0) 99 | { 100 | nearest=dist; 101 | ni=k; 102 | } 103 | if(dist revise(vector ¢roids,int x,int y) 118 | { 119 | int size=centroids.size(); 120 | vector revised; 121 | int threshold=(x*y*10)/1000; 122 | for(int i=0;ithreshold) 125 | { 126 | centroids[i].counter=0; 127 | revised.push_back(centroids[i]); 128 | } 129 | } 130 | return revised; 131 | } 132 | int main() 133 | { 134 | string name="nebullfa.jpg"; 135 | Mat image; 136 | image=imread(name); 137 | int x=image.rows; 138 | int y=image.cols; 139 | int r_hist[256]; 140 | int b_hist[256]; 141 | int g_hist[256]; 142 | int rh[4][256]={{0},{0},{0},{0}}; 143 | int bh[4][256]={{0},{0},{0},{0}}; 144 | int gh[4][256]={{0},{0},{0},{0}}; 145 | int rm_hist[256]; 146 | int bm_hist[256]; 147 | int gm_hist[256]; 148 | vector rpeaks; 149 | vector bpeaks; 150 | vector gpeaks; 151 | //Make the histogram 152 | #pragma omp parallel 153 | { 154 | #pragma omp for schedule(dynamic,x/4) 155 | for(int i=0;i(i,j)[2]; 161 | int gval=image.at(i,j)[1]; 162 | int bval=image.at(i,j)[0]; 163 | rh[id][rval]++; 164 | bh[id][bval]++; 165 | gh[id][gval]++; 166 | } 167 | } 168 | #pragma omp for schedule(dynamic,64) 169 | for(int i=0;i<256;i++) 170 | { 171 | r_hist[i]=rh[0][i]+rh[1][i]+rh[2][i]+rh[3][i]; 172 | g_hist[i]=gh[0][i]+gh[1][i]+gh[2][i]+gh[3][i]; 173 | b_hist[i]=bh[0][i]+bh[1][i]+bh[2][i]+bh[3][i]; 174 | } 175 | #pragma omp sections 176 | { 177 | #pragma omp section 178 | smoothen(r_hist,rm_hist); 179 | #pragma omp section 180 | smoothen(g_hist,gm_hist); 181 | #pragma omp section 182 | smoothen(b_hist,bm_hist); 183 | } 184 | #pragma omp sections 185 | { 186 | #pragma omp section 187 | rpeaks=peak_finder(rm_hist,x,y); 188 | #pragma omp section 189 | gpeaks=peak_finder(gm_hist,x,y); 190 | #pragma omp section 191 | bpeaks=peak_finder(bm_hist,x,y); 192 | } 193 | } 194 | vector parents(x*y); 195 | vector centroids=centroid_finder(rpeaks,gpeaks,bpeaks); 196 | assign_centroid(centroids,image,parents); 197 | cout<<"assign"< revCentroids=revise(centroids,x,y); 199 | centroids.clear(); 200 | cout<(i,j)[0]=revCentroids[parents[i*y+j]].b; 208 | image.at(i,j)[1]=revCentroids[parents[i*y+j]].g; 209 | image.at(i,j)[2]=revCentroids[parents[i*y+j]].r; 210 | } 211 | } 212 | imwrite("edited_histp.png",image); 213 | //resize(image,image,cvSize(600,400)); 214 | waitKey(5000); 215 | } 216 | -------------------------------------------------------------------------------- /hist_seg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cb1711/Image-Segmentation/905633bf1406d59de5ac3af17f1f974fdc38d206/hist_seg.png -------------------------------------------------------------------------------- /imgcmp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include 6 | using namespace std; 7 | using namespace cv; 8 | int main() 9 | { 10 | Mat img1,img2,img3; 11 | string name="edited_histp.png"; 12 | string name2="edited_hist.png"; 13 | img1=imread(name); 14 | img2=imread(name2); 15 | img3=imread(name2); 16 | int y=img1.cols; 17 | for(int i=0;i(i,j)[0]==img2.at(i,j)[0] && img1.at(i,j)[1]==img2.at(i,j)[1] && img1.at(i,j)[2]==img2.at(i,j)[2]) 24 | { 25 | img3.at(i,j)[0]=0; 26 | img3.at(i,j)[1]=0; 27 | img3.at(i,j)[2]=0; 28 | } 29 | else{ 30 | img3.at(i,j)[0]=255; 31 | img3.at(i,j)[1]=255; 32 | img3.at(i,j)[2]=255; 33 | } 34 | 35 | } 36 | } 37 | imwrite("diff.png",img3); 38 | resize(img3,img3,cvSize(500,700)); 39 | imshow("diff",img3); 40 | waitKey(5000); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /kmeans.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "opencv2/highgui/highgui.hpp" 3 | #include 4 | #include 5 | using namespace std; 6 | using namespace cv; 7 | #define ll long long 8 | #define rep(i,n) for(int i=0;i 11 | #define vii vector< vi > 12 | #define pb push_back 13 | #define mp make_pair 14 | #define fi first 15 | #define se second 16 | #define pii pair 17 | #define all(c) c.begin(),c.end() 18 | #define sz(c) c.size() 19 | struct Node 20 | { 21 | ll r,g,b; 22 | }; 23 | typedef struct Node node; 24 | int main() 25 | { 26 | ll N,M; 27 | string img="kmeans.jpg"; 28 | Mat image,pq; 29 | image=imread(img); 30 | pq=imread(img); 31 | ll N1=image.rows; 32 | ll M1=image.cols; 33 | //resize(image,image,cvSize(N1/2,M1/2)); 34 | //resize(pq,pq,cvSize(N1/2,M1/2)); 35 | N=image.rows; 36 | M=image.cols; 37 | vector< vector > arr(N); 38 | rep(i,N) 39 | { 40 | rep(j,M) 41 | { 42 | node z; 43 | z.b=image.at(i,j)[0]; 44 | z.g=image.at(i,j)[1]; 45 | z.r=image.at(i,j)[2]; 46 | arr[i].pb(z); 47 | //cout<<"("<>K>>ss; 54 | srand(time(0)); 55 | vector cluster(K),temp(K); 56 | vi c(K); 57 | //vector color(K); 58 | rep(i,K) cluster[i]=mp(rand()%N,rand()%M); 59 | /*rep(i,K) 60 | { 61 | color[i].r=rand()%255; 62 | color[i].g=rand()%255; 63 | color[i].b=rand()%255; 64 | }*/ 65 | while(ss--) 66 | { 67 | cout< > mat(N,vector(M,mp(hell,-1))); 69 | rep(i,K) temp[i]=mp(0,0),c[i]=1; 70 | rep(i,N) 71 | { 72 | rep(j,M) 73 | { 74 | rep(k,K) 75 | { 76 | ll d=(arr[i][j].r-arr[cluster[k].fi][cluster[k].se].r)*(arr[i][j].r-arr[cluster[k].fi][cluster[k].se].r); 77 | d+=(arr[i][j].b-arr[cluster[k].fi][cluster[k].se].b)*(arr[i][j].b-arr[cluster[k].fi][cluster[k].se].b); 78 | d+=(arr[i][j].g-arr[cluster[k].fi][cluster[k].se].g)*(arr[i][j].g-arr[cluster[k].fi][cluster[k].se].g); 79 | //d+=3*((i-cluster[k].fi)*(i-cluster[k].fi)+(j-cluster[k].se)*(j-cluster[k].se)); 80 | if(d(i,j)[0]=image.at(cluster[k].fi,cluster[k].se)[0]; 109 | pq.at(i,j)[1]=image.at(cluster[k].fi,cluster[k].se)[1]; 110 | pq.at(i,j)[2]=image.at(cluster[k].fi,cluster[k].se)[2]; 111 | } 112 | } 113 | } 114 | resize(pq,pq,cvSize(500,500)); 115 | imshow("image",pq); 116 | waitKey(1000000); 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /kmeans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cb1711/Image-Segmentation/905633bf1406d59de5ac3af17f1f974fdc38d206/kmeans.png -------------------------------------------------------------------------------- /otsu.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include 6 | #include 7 | using namespace cv; 8 | using namespace std; 9 | float var(int hist[],int level,float val,int pix_num ) 10 | { 11 | long long total=pix_num*val; 12 | int n=0; 13 | long long m=0; 14 | for(int i=0;i(i,j); 43 | u+=n; 44 | hist[n]++; 45 | } 46 | } 47 | int pix_num=img.rows*img.cols; 48 | float val=(1.0*u)/float(pix_num); 49 | float max=0; 50 | int threshold=0; 51 | for(int i=1;i<255;i++) 52 | { 53 | int x=var(hist,i,val,pix_num); 54 | if(x>max) 55 | { 56 | max=x; 57 | threshold=i; 58 | } 59 | } 60 | for(int i=0;i(i,j)>threshold) 65 | { 66 | img.at(i,j)=255; 67 | } 68 | else 69 | img.at(i,j)=0; 70 | } 71 | } 72 | imwrite("otsu.png",img); 73 | waitKey(5000); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /otsu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cb1711/Image-Segmentation/905633bf1406d59de5ac3af17f1f974fdc38d206/otsu.png -------------------------------------------------------------------------------- /seg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include 6 | using namespace std; 7 | using namespace cv; 8 | struct pixel{ 9 | int x; 10 | int y; 11 | }; 12 | bool use=false; 13 | typedef struct un un; 14 | typedef struct pixel pixel; 15 | struct edge{ 16 | float weigh; 17 | pixel node1; 18 | pixel node2; 19 | }; 20 | typedef struct edge edge; 21 | float weight(int p1[],int p2[]) 22 | { 23 | float weight=(p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]); 24 | weight=sqrt(weight); 25 | return weight; 26 | } 27 | int root (vector &Arr ,int i) 28 | { 29 | while(Arr[i]!= i) 30 | { 31 | Arr[i] = Arr[Arr[i]] ; 32 | i = Arr[i]; 33 | } 34 | return i; 35 | } 36 | int main() 37 | { 38 | Mat img1; 39 | int np=4; 40 | float k=30/np+1; 41 | string name="nebullfa.jpg"; 42 | img1=imread(name); 43 | //resize(img1,img1,cvSize(1920,1080)); 44 | //resize(img1,img1,cvSize(500,700)); 45 | int x=img1.rows; 46 | int y=img1.cols; 47 | cout< edges; 50 | vector Array(x*y); 51 | vector Size(x*y); 52 | vector cheapest(x*y); 53 | vector Earray(x*y); 54 | int chunk=(y)/16; 55 | 56 | for(int i=0;i(i,j)[0]; 67 | t1[1]=img1.at(i,j)[1]; 68 | t1[2]=img1.at(i,j)[2]; 69 | t2[0]=img1.at(i+1,j)[0]; 70 | t2[1]=img1.at(i+1,j)[1]; 71 | t2[2]=img1.at(i+1,j)[2]; 72 | edge e1; 73 | e1.weigh=weight(t1,t2); 74 | e1.node1.x=i; 75 | e1.node1.y=j; 76 | e1.node2.x=i+1; 77 | e1.node2.y=j; 78 | edges.push_back(e1); 79 | } 80 | else if(i==x-1) 81 | { 82 | int t1[3]; 83 | int t2[3]; 84 | t1[0]=img1.at(i,j)[0]; 85 | t1[1]=img1.at(i,j)[1]; 86 | t1[2]=img1.at(i,j)[2]; 87 | t2[0]=img1.at(i,j+1)[0]; 88 | t2[1]=img1.at(i,j+1)[1]; 89 | t2[2]=img1.at(i,j+1)[2]; 90 | edge e1; 91 | e1.weigh=weight(t1,t2); 92 | e1.node1.x=i; 93 | e1.node1.y=j; 94 | e1.node2.x=i; 95 | e1.node2.y=j+1; 96 | edges.push_back(e1); 97 | } 98 | else{ 99 | int t1[3]; 100 | int t2[3]; 101 | t1[0]=img1.at(i,j)[0]; 102 | t1[1]=img1.at(i,j)[1]; 103 | t1[2]=img1.at(i,j)[2]; 104 | t2[0]=img1.at(i+1,j)[0]; 105 | t2[1]=img1.at(i+1,j)[1]; 106 | t2[2]=img1.at(i+1,j)[2]; 107 | edge e1; 108 | e1.weigh=weight(t1,t2); 109 | e1.node1.x=i; 110 | e1.node1.y=j; 111 | e1.node2.x=i+1; 112 | e1.node2.y=j; 113 | edges.push_back(e1); 114 | t2[0]=img1.at(i,j+1)[0]; 115 | t2[1]=img1.at(i,j+1)[1]; 116 | t2[2]=img1.at(i,j+1)[2]; 117 | e1.weigh=weight(t1,t2); 118 | e1.node2.x=i; 119 | e1.node2.y=j+1; 120 | edges.push_back(e1); 121 | } 122 | } 123 | } 124 | cout<<"hello world"<edges[i].weigh) 173 | cheapest[ra]=i; 174 | if(cheapest[rc]==-1 || edges[cheapest[rc]].weigh>edges[i].weigh) 175 | cheapest[rc]=i; 176 | } 177 | } 178 | temp=0; 179 | int starter=(x*y)/np*p; 180 | int ender=((x*y)/np)*(p+1); 181 | if (p==np-1) 182 | ender=x*y; 183 | for(int i=starter;iT2?T2:T1; 202 | //condition for merging the two trees 203 | if (b.weigh<=min) 204 | { 205 | //union 206 | if(Size[ra]>Size[rb]) 207 | { 208 | Size[ra]+=Size[rb]; 209 | Array[rb]=ra; 210 | if(edges[cheapest[i]].weigh>Earray[ra]) 211 | Earray[ra]=edges[cheapest[i]].weigh; 212 | if (Earray[ra]<=Earray[rb]) 213 | Earray[ra]=Earray[rb]; 214 | cheapest[ra]=-1; 215 | } 216 | else 217 | { 218 | Size[rb]+=Size[ra]; 219 | Array[ra]=rb; 220 | if(edges[cheapest[i]].weigh>Earray[rb]) 221 | Earray[rb]=edges[cheapest[i]].weigh; 222 | if (Earray[rb]<=Earray[ra]) 223 | Earray[rb]=Earray[ra]; 224 | cheapest[rb]=-1; 225 | } 226 | temp++; 227 | } 228 | } 229 | } 230 | counter-=temp; 231 | if(t==counter) 232 | flag=1; 233 | } 234 | } 235 | } 236 | //to merge the image segments made by each processor separately 237 | #pragma omp parallel for 238 | for(int i=0;iT2?T2:T1; 257 | if (b.weigh<=min/2) 258 | { 259 | //union 260 | if(Size[ra]>Size[rb]) 261 | { 262 | Size[ra]+=Size[rb]; 263 | Array[rb]=ra; 264 | } 265 | else 266 | { 267 | Size[rb]+=Size[ra]; 268 | Array[ra]=rb; 269 | } 270 | } 271 | } 272 | } 273 | #pragma omp parallel for schedule(dynamic,chunk) 274 | for(int i=0;i(xcoord,ycoord)[0]=img1.at(rcx,rcy)[0]; 282 | img1.at(xcoord,ycoord)[2]=img1.at(rcx,rcy)[2]; 283 | img1.at(xcoord,ycoord)[1]=img1.at(rcx,rcy)[1]; 284 | // if(rc==root(Array,0)) 285 | // { 286 | // img1.at(xcoord,ycoord)[0]=0; 287 | // img1.at(xcoord,ycoord)[2]=0; 288 | // img1.at(xcoord,ycoord)[1]=0; 289 | // } 290 | } 291 | time=omp_get_wtime()-time; 292 | cout< 2 | #include 3 | #include 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include 6 | using namespace std; 7 | using namespace cv; 8 | 9 | struct pixel{ 10 | int x; 11 | int y; 12 | }; 13 | 14 | bool use=false; 15 | typedef struct un un; 16 | typedef struct pixel pixel; 17 | struct edge{ 18 | float weigh; 19 | pixel node1; 20 | pixel node2; 21 | }; 22 | typedef struct edge edge; 23 | float weight(int p1[],int p2[]) 24 | { 25 | float weight=(p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]); 26 | weight=sqrt(weight); 27 | return weight; 28 | } 29 | int root (vector &Arr ,int i) 30 | { 31 | 32 | while(Arr[i]!= i) 33 | { 34 | Arr[i] = Arr[Arr[i]] ; 35 | i = Arr[i]; 36 | } 37 | return i; 38 | } 39 | int main() 40 | { 41 | Mat img1; 42 | float k=20; 43 | string name="a.tif"; 44 | img1=imread(name); 45 | //resize(img1,img1,cvSize(10,10)); 46 | int x=img1.rows; 47 | int y=img1.cols; 48 | cout< edges; 51 | vector Array(x*y); 52 | vector Size(x*y); 53 | vector cheapest(x*y); 54 | vector Earray(x*y); 55 | vector locks(x*y); 56 | int chunk=(y)/16; 57 | 58 | for(int i=0;i(i,j)[0]; 70 | t1[1]=img1.at(i,j)[1]; 71 | t1[2]=img1.at(i,j)[2]; 72 | t2[0]=img1.at(i+1,j)[0]; 73 | t2[1]=img1.at(i+1,j)[1]; 74 | t2[2]=img1.at(i+1,j)[2]; 75 | edge e1; 76 | e1.weigh=weight(t1,t2); 77 | e1.node1.x=i; 78 | e1.node1.y=j; 79 | e1.node2.x=i+1; 80 | e1.node2.y=j; 81 | edges.push_back(e1); 82 | } 83 | else if(i==x-1) 84 | { 85 | int t1[3]; 86 | int t2[3]; 87 | t1[0]=img1.at(i,j)[0]; 88 | t1[1]=img1.at(i,j)[1]; 89 | t1[2]=img1.at(i,j)[2]; 90 | t2[0]=img1.at(i,j+1)[0]; 91 | t2[1]=img1.at(i,j+1)[1]; 92 | t2[2]=img1.at(i,j+1)[2]; 93 | edge e1; 94 | e1.weigh=weight(t1,t2); 95 | e1.node1.x=i; 96 | e1.node1.y=j; 97 | e1.node2.x=i; 98 | e1.node2.y=j+1; 99 | edges.push_back(e1); 100 | } 101 | else{ 102 | int t1[3]; 103 | int t2[3]; 104 | t1[0]=img1.at(i,j)[0]; 105 | t1[1]=img1.at(i,j)[1]; 106 | t1[2]=img1.at(i,j)[2]; 107 | t2[0]=img1.at(i+1,j)[0]; 108 | t2[1]=img1.at(i+1,j)[1]; 109 | t2[2]=img1.at(i+1,j)[2]; 110 | edge e1; 111 | e1.weigh=weight(t1,t2); 112 | e1.node1.x=i; 113 | e1.node1.y=j; 114 | e1.node2.x=i+1; 115 | e1.node2.y=j; 116 | // cout<<(2*(i*y+j))-i; 117 | edges.push_back(e1); 118 | t2[0]=img1.at(i,j+1)[0]; 119 | t2[1]=img1.at(i,j+1)[1]; 120 | t2[2]=img1.at(i,j+1)[2]; 121 | e1.weigh=weight(t1,t2); 122 | e1.node2.x=i; 123 | e1.node2.y=j+1; 124 | edges.push_back(e1); 125 | //cout<<"e"; 126 | } 127 | } 128 | } 129 | 130 | //#pragma omp for schedule(dynamic,x*y/30) 131 | cout<<"Hello world"<edges[i].weigh) 171 | { 172 | //#pragma omp atomic write 173 | //#pragma omp critical 174 | cheapest[ra]=i; 175 | //omp_unset_lock(&locks[ra]); 176 | } 177 | if(cheapest[rc]==-1 || edges[cheapest[rc]].weigh>edges[i].weigh) 178 | { 179 | //#pragma omp critical 180 | //#pragma omp atomic write 181 | //#pragma omp critical 182 | cheapest[rc]=i; 183 | //omp_unset_lock(&locks[rc]); 184 | } 185 | } 186 | } 187 | temp=0; 188 | //#pragma omp parallel for schedule(dynamic,x*y/8) reduction(+:temp) 189 | //#pragma omp master 190 | #pragma omp parallel for schedule(dynamic,x*y/30) 191 | for(int i=0;iT2?T2:T1; 226 | //condition for merging the two trees 227 | if (b.weigh<=min) 228 | { 229 | //union 230 | if(Size[ra]>Size[rb]) 231 | { 232 | Size[ra]+=Size[rb]; 233 | Array[rb]=ra; 234 | if(edges[cheapest[i]].weigh>Earray[ra]) 235 | Earray[ra]=edges[cheapest[i]].weigh; 236 | if (Earray[ra]<=Earray[rb]) 237 | Earray[ra]=Earray[rb]; 238 | cheapest[ra]=-1; 239 | //cout<<"df"; 240 | } 241 | else 242 | { 243 | Size[rb]+=Size[ra]; 244 | Array[ra]=rb; 245 | if(edges[cheapest[i]].weigh>Earray[rb]) 246 | Earray[rb]=edges[cheapest[i]].weigh; 247 | if (Earray[rb]<=Earray[ra]) 248 | Earray[rb]=Earray[ra]; 249 | cheapest[rb]=-1; 250 | } 251 | temp++; 252 | } 253 | omp_unset_lock(&locks[a]); 254 | omp_unset_lock(&locks[c]); 255 | } 256 | } 257 | counter-=temp; 258 | if(t==counter) 259 | flag=1; 260 | } 261 | #pragma omp parallel for schedule(dynamic,chunk) 262 | for(int i=0;i(xcoord,ycoord)[0]=img1.at(rcx,rcy)[0]; 269 | img1.at(xcoord,ycoord)[2]=img1.at(rcx,rcy)[2]; 270 | img1.at(xcoord,ycoord)[1]=img1.at(rcx,rcy)[1]; 271 | } 272 | time=omp_get_wtime()-time; 273 | cout<