:
"Before retrieving"
"After retrieving"
Function:
Clicking find table of contents randomly displays 6 images in the current directory, which is displayed if the current directory is less than 6.
Click Select to display the test image above the Select button.
Click Retrieve to display the 6 images that are closest to the current image color below.
Ideas:
The RGB space of the image is mapped to the HSV space and its H, S, and V are divided into 12 intervals. So the image gets 3*12 properties.
The above processing is done for the selected test image and all the images to be retrieved.
The distance between the test image and the retrieved image is calculated, and the resulting distance is sorted in order from small to large, and the top 6 images are displayed in the search box.
The distance can be calculated using a typical Euclidean distance.
Steps:
1. The HSV attribute of the test image will be computed.
2. Calculates the HSV attribute for each image in the current directory and calculates the distance between it and the HSV property of the test image.
3. Sort the resulting distances.
4. Display the image according to the sorted results.
Part of the code:
"Find Directory"
void Ccbirlsdlg::onbnclickedbutton2 () {//Todo:add your control notification handler code here//use the BROWSEINFO structure to open the common dialog box, Get user-selected directory information Browseinfo browse; ZeroMemory (&browse,sizeof (browse)); Browse.hwndowner = Null;browse.pszdisplayname = Spath.getbuffer (MAX_PATH); /browse.lpsztitle=s;//returns information about the selected folder Lpitemidlist Lpitem = SHBrowseForFolder (&browse), if (Lpitem = = NULL) return; Spath.releasebuffer ();//shgetpathfromidlist convert the item marker list to the Document System path if (SHGetPathFromIDList (Lpitem,spath.getbuffer (MAX_ PATH) = = false) return; Spath.releasebuffer (); Spath.trim ();////////////////////pending int tempi=0;counts=0;//counter clear 0////////////////////pending//afxmessagebox (SPath); /Retrieve the number of images in the library into the counts, and its path into the temp[100] bool flag; CFileFind find; Char tempfilefind[200]; sprintf_s (Tempfilefind, "%s\\*.bmp", spath); sprintf_s (Tempfilefind, "%s\\*.bmp", spath); Flag = Find. FindFile (Tempfilefind); Locate the BMP file LPWStr Myfilename;//path in the current directory. Setwindowtexta (spath); Path associated with the text box. while (flag) {flag = find. FindNextFile (); Char foundfilename[200];//temporary storage checkLocate the image name//strcpy_s (foundfilename,find. GetFileName (). GetBuffer (200));//Gets the image name//strcpy (foundfilename,find. GetFileName (). GetBuffer (200));//Gets the image name//strcpy_s//myfilename=find. GetFileName (). GetBuffer (strcpy_s); Foundfilename,find. GetFileName (). GetBuffer (+));//strcpy_s (Foundfilename,find. GetFileName (). GetBuffer,//afxmessagebox (foundfilename);//path. SETWINDOWTEXTW (Foundfilename);//strcpy (foundfilename,&myfilename); if (!find. Isdots ())//filter default directory {char tempfilename[200];sprintf_s (tempfilename, "%s\\%s", spath,foundfilename);//cstring Strfilepath1;//strfilepath1. Format ("%s", tempfilename);//Get Image full path imagesource[counts] = new CString (tempfilename);//Save Image Full path counts++;// AfxMessageBox (imagesource[counts],mb_iconinformation| MB_OK);//afxmessagebox (imagesource[counts]);//databaseimage.load (imagesource[counts]);//AfxMessageBox (* Imagesource[counts]);//path. Setwindowtexta (Imagesource[counts]);} } find. Close (); CString Temps;//temps. Format ("There are%d images in this directory!", counts);//AfxMessageBox (Temps,mb_iconinformation| MB_OK);//afxmessagebox ("The directory you selected is:" +spath,mb_iconinformation| MB_OK);//strcat ("Current path:", spath);//randomly display the image below, if it is less than six, all display, more than 6, randomly display six//cstring result;/*pic[1]= "RESULT1";p ic[2]= "Result2";p ic[3]= "RESULT3";p ic[4]= "RESULT4";p ic[5]= "RESULT5";p ic[6]= "result6"; *///Displays the image under the current directory, showing the first 6 images obtained, If less than 6, displays only the existing image if (counts<6) showcounts=counts;elseshowcounts=6;for (int i=0;i<counts;i++) {is[i]=* Imagesource[i];//afxmessagebox (*imagesource[i]);} id=1006; Here the ID of the RESULT2 is 1006, and so on, RESULT6 is 1011for (int i=0;i<showcounts;i++) {if (!databaseimage.isnull ())//To determine whether the image is empty, If not empty, first release Databaseimage.destroy ();//databaseimage.load (Is[i]);d atabaseimage.load (Is[i]); CRect rect; CWnd *pwnd = GetDlgItem (id++); CDC *PDC = PWND->GETDC ();//1th Control Pwnd->getclientrect (&rect); Obtain customer area size Pdc->setstretchbltmode (stretch_halftone); Keep the picture Databaseimage.draw (Pdc->m_hdc,rect); The size of the control dimension to draw ReleaseDC (PDC);} Path. SETWINDOWTEXTW (spath); Path associated with the text box. The search path for the setting is displayed here in the text box. Path. Setwindowtexta (spath); SETWINDOWTEXTW is a function used under a single character set}
Select
void Ccbirlsdlg::onbnclickedbutton1 () {//Todo:add your control notification handler code Herecfiledialog FILEDLG (TRUE, null,null,ofn_allowmultiselect,_t ("Picture Files (*.bmp *.jpg) |*bmp;; *jpg| | "), AfxGetMainWnd ()); CString pathname;if (filedlg.domodal () = = IDOK) { POSITION MPos = filedlg.getstartposition (); if (Mpos!=null) { pathName = (LPCTSTR) filedlg.getpathname (), if (!myimage.isnull ())//To determine whether the image is empty, if not empty first release Myimage.destroy (); Myimage.load (pathName);} } CRect rect; CWnd *pwnd = GetDlgItem (IDC_MY_PIC2); CDC *PDC = PWND->GETDC ();//1th Control Pwnd->getclientrect (&rect); Obtain customer area size Pdc->setstretchbltmode (stretch_halftone); Keep the picture Myimage.draw (Pdc->m_hdc,rect); The size of the control size to draw ReleaseDC (PDC);//myimage.destroy ();}
Retrieve
void Ccbirlsdlg::onbnclickedbutton3 () {//Todo:add your control notification handler code here/*if (Myimage.isnull ()) { AfxMessageBox (_t ("Please select an image to retrieve first"); return;} if (Spath.isempty ()) {AfxMessageBox ("Please select the path to retrieve first"); return;} */colorref color;double H=0,s=0,v=0;long mygraph[3][13]; Used to store the HSV space value double sourcefeature[3][12];//the color characteristics of the image to be retrieved double tempfeature[3][12]; The feature used to store files in the retrieved directory int maxx,maxy;int totalnum;for (int i=0;i<3;i++) for (int j=0;j<13;j++) {mygraph[i][j]=0;} Maxx=myimage.getwidth (); Maxy=myimage.getheight (); totalnum=maxx*maxy;for (int i=0; i<maxx-1; i++) {for (int j=0; j <maxY-1; J + +) {color=myimage.getpixel (i,j); RGB2HSV (Getrvalue (color), getgvalue (color), getbvalue (color), &h,&s,&v); int result_h= (int) (6*h/ 3.1415926); int result_s= (int) (S*12); int result_v= (int) (v*12); mygraph[0][result_h]++;mygraph[1][result_s]++;mygraph[2][result_v]++;}} for (int i=0;i<3;i++) for (int j=0;j<12;j++) {sourcefeature[i][j]= ((float) mygraph[i][j])/((float) totalnum);} Calculates the distance between each image and the image to be retrieved. for (int i=0; i<counts;i++) distance[i]=0;for (int ch=0;ch<counts;ch++) {for (Int. i=0;i<3;i++) for (int j=0;j<13;j++) { mygraph[i][j]=0;} if (!databaseimage.isnull ())//To determine whether the image is empty, if not empty first release Databaseimage.destroy ();//databaseimage.load (Is[i]); Databaseimage.load (Is[ch]);//test, whether the correct image is shown AfxMessageBox (Is[ch]); Maxx=databaseimage.getwidth (); maxy= Databaseimage.getheight (); totalnum=maxx*maxy;for (int i=0; i<maxx-1; i++) {for (int j=0; j<maxy-1; J + +) {color= Databaseimage.getpixel (I,J); RGB2HSV (Getrvalue (color), getgvalue (color), getbvalue (color), &h,&s,&v); int result_h= (int) (6*h/ 3.1415926); int result_s= (int) (S*12); int result_v= (int) (V*12), mygraph[0][result_h]++;mygraph[1][result_s]++;mygraph[2][result_v]++;//is not processed here for a condition equal to 12 , the probability is very small, but still may error, need attention. }}double distancetemp=0; Here, has been defined as int type, wrong wrong!!! for (int i=0;i<3;i++) {for (int j=0;j<12;j++) {tempfeature[i][j]= ((float) mygraph[i][j])/((float) totalnum); distancetemp+= (Tempfeature[i][j]-sourcefeature[i][j]) * (Tempfeature[i][j]-sourcefeature[i][j]);} DistANCE[CH]+=SQRT (double) distancetemp);d istancetemp=0;} The image is initially scrambled and then displayed. Test location/*cstring str;//double w=0.33;str. Format ("%lf", Distance[ch]); AfxMessageBox (str); *////////////////////test position}//sorting, so that the smaller distance of the image is displayed in the earlier position. imagesourceresult=imagesource;for (int i=0;i<counts;i++) {imagesourceresult[i]=*imagesource[i];// AfxMessageBox (*imagesource[i]);} Double Tempdis; CString temppic;///////////Test/*for (int i=0;i<counts-1;i++) if (distance[i]=distance[i+1]) {AfxMessageBox ("game Error ");} if (distance[0]==0) AfxMessageBox ("Game error");//afxmessagebox (distance[0]); CString str; for (int i=0;i<counts;i++) {str. Format ("%d", distance[i]); AfxMessageBox (str);} *////////////test for (int i=0;i<counts;i++) {for (int j=i+1;j<counts;j++) {if (Distance[i]>distance[j]) {// AfxMessageBox ("Game error"); temppic=imagesourceresult[i];tempdis=distance[i];imagesourceresult[i]= IMAGESOURCERESULT[J];d Istance[i]=distance[j];imagesourceresult[j]=temppic;distance[j]=tempdis;}}} id=1006; Set the picture control control that is displayedThe starting ID number for (int i=0;i<showcounts;i++) {if (!databaseimage.isnull ())//Determines whether the image is empty, and if not empty, first releases the Databaseimage.destroy (); /databaseimage.load (Is[i]);d atabaseimage.load (Imagesourceresult[i]); CRect rect; CWnd *pwnd = GetDlgItem (id++); CDC *PDC = PWND->GETDC ();//1th Control Pwnd->getclientrect (&rect); Obtain customer area size Pdc->setstretchbltmode (stretch_halftone); Keep the picture Databaseimage.draw (Pdc->m_hdc,rect); The size of the control dimension to draw ReleaseDC (PDC);} AfxMessageBox ("Search done! ");}
"Partial functions, etc."
CImage ccbirlsdlg::rgb2hsv (void) {return CImage ();} CImage CCBIRLSDLG::RGB2HSV (CImage * sourceimage) {return CImage ();} void Ccbirlsdlg::rgb2hsv (int r, int g, int b, double *h, double *s, double *v) {*h=acos ((r-g+r-b)/(2.0*sqrtf ((float) (r-g ) * (R-G) + (float) (r-b) * (G-b))), if (b>g) *h=2*3.1415926-*h;*s= (Max (r,g,b)-min (r,g,b))/(float) MAX (r,g,b); *v=max ( R,G,B)/255.0;} int Ccbirlsdlg::max (int a, int b, int c) {int m;if (a>b) m=a;elsem=b;if (m<c) M=c;return m;} int ccbirlsdlg::min (int a, int b, int c) {int m;if (a<b) m=a;else m=b;if (m>c) M=c;return m;} void Ccbirlsdlg::onbnclickedbutton4 () {//Todo:add your control notification handler code Herecdialog::oncancel ();}
Implementing the Environment:
VS2010
Resources:
Visual C + + Digital Image processing typical case, the 8th chapter, Image Retrieval system.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Color-based learning system for image retrieval