The following figure shows part of a program coded in C that builds and runs a QBIC query. The code in the figure queries images by average color. It prompts the user to enter the name of a color or image file. The user can also use an image that is returned by a query as an example image for a subsequent query. The program then uses the named color or the color of the image as the average color to query a column of images.
You can find the complete program in the QBICDEMO.C file in the SAMPLES subdirectory. The complete program can be used to query images by histogram color or positional color as well as by average color. To run the complete program, you must run the ENABLE, POPULATE, and QBCATDMO sample programs (also in the SAMPLES subdirectory). For more information about the sample programs, see Appendix B, Sample programs and media files.
Note the following points in the sample program:
(1)Include the dmbqbapi header file.
(2)Prompt the user for database information.
(3)Connect to the database.
(4)Create a query object.
(5)Add a feature to the query object.
(6)Prompt the user for the type of input (color name, image file, or previously retrieved image).
(7)Specify the data source for the feature. The data source is an explicit specification for average color.
(8)Issue the query. The Image Extender searches the entire column of images. It also specifies 10 as the maximum number of images to be returned.
(9)Display the next image in the set of returned images. For further information on displaying images, see Displaying a full-size image or video frame.
(10)Delete the query object.
The SAMPLES subdirectory includes another program that demonstrates how to build and use a QBIC query. The program, QbicQry.java, shows you how to graphically specify the search criteria for a QBIC query. For example, the program presents a color selector to choose average color. The program converts the selection to a query string.
Figure 21. QBIC query sample program
#include <sql.h> #include <sqlcli.h> #include <sqlcli1.h> #include <dmbqbqpi.h> (1) #include <stdio.h> #include <string.h> #include <malloc.h> #include <color.h> #include <ctype.h> #define MaxQueryReturns 10 #define MaxDatabaseNameLength SQL_SH_IDENT #define MaxUserIdLength SQL_SH_IDENT #define MaxPasswordLength SQL_SH_IDENT #define MaxTableNameLength SQL_LG_IDENT #define MaxColumnNameLength SQL_LG_IDENT static char databaseName[MaxDatabaseNameLength+1]; static char userid[MaxUserIdLength+1]; static char password[MaxPasswordLength+1]; static char tableName[MaxTableNameLength+1]; static char columnName[MaxColumnNameLength+1]; static char line[4000]; static QbResult results[MaxQueryReturns]; static long currentImage = -1; static long imageCount = 0; static char* tableAndColumn; static QbQueryHandle averageHandle = 0; static QbQueryHandle histogramHandle = 0; static QbQueryHandle drawHandle = 0; static QbQueryHandle lastHandle = 0; static SQLHENV henv; static SQLHDBC hdbc; static SQLHSTMT hstmt; static SQLRETURN rc; static char* listQueries = "SELECT NAME,DESCRIPTION FROM MMDBSYS.QBICQUERIES ORDER BY NAME"; static char* menu[] = { /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ "", "+-----------------------------------------------------------------------------+", "| AVERAGE COLOR colorname |", "| AVERAGE FILE filename format |", "| AVERAGE LAST |", "| Press Enter to display the next image in the series |", "+-----------------------------------------------------------------------------+", "", 0 }; static char* help[] = { "", "AVERAGE Execute an average color query", " COLOR Specifies the color to query for", " FILE Specifies the file to compute the average color from", " LAST Specifies the last displayed image be used to compute the color", " NEXT Displays the next image from the current query or nothing if", " all of the image have been displayed." "", ">>pause<<", 0 }; /******************************************************************************/ /* doNext() */ /******************************************************************************/ static void doNext(void) { int ret; if (currentImage < imageCount) currentImage++; if (currentImage < imageCount) ret = DBiBrowse("/usr/local/bin/xv %s", MMDB_PLAY_HANDLE, results[currentImage].imageHandle, MMDB_PLAY_NO_WAIT); (9) } /******************************************************************************/ /* doAverage() */ /******************************************************************************/ static void doAverage(void) { QbQueryHandle qohandle = 0; QbImageSource is; char* type; char* arg1; char* arg2; type = nextWord(0); if (abbrev(type, "color", 1)) { is.type = qbiSource_AverageColor; arg1 = nextWord(0); if (arg1 == 0) { printf("AVERAGE COLOR command requires a colorname argument.\n"); return; } if (getColor(arg1, &is.averageColor) == 0) { printf("The colorname entered was not recognized.\n"); return; } } else if (abbrev(type, "file", 1)) { is.type = qbiSource_ClientFile; arg1 = nextWord(0); if (arg1 == 0) { printf("AVERAGE FILE command requires a filename argument.\n"); return; } arg2 = nextWord(0); if (arg2 == 0) { printf("AVERAGE FILE command requires a file format argument.\n"); return; } strcpy(is.clientFile.fileName, arg1); strcpy(is.clientFile.format, arg2); } else if (abbrev(type, "last", 1)) { is.type = qbiSource_ImageHandle; if (0 <= currentImage &&; currentImage < imageCount) strcpy(is.imageHandle, results[currentImage]imageHandle); else { printf("No last image for AVERAGE LAST command\n"); return; } } else { printf("AVERAGE command only supports COLOR, FILE, and LAST types.\n"); return; } _QbQuerySetFeatureData(averageHandle, "QbColorFeatureClass", &is); (7) _QbQuerySearch(averageHandle, tableAndColumn, "IMAGE", MaxQueryReturns, 0, 0, &imageCount, results); (8) lastHandle = averageHandle; currentImage = -1; } /******************************************************************************/ /* commandLoop() */ /******************************************************************************/ void commandLoop(void) { int done = 0; while (!done) { (6) displayText(menu); printf("%d", currentImage + 1); if (0 <= currentImage &&; currentImage < imageCount) printf(" %8.6f", results[currentImage].score); printf("> "); gets(line); done = processCommand(line); } } /******************************************************************************/ /* main() */ /******************************************************************************/ void main(void) { char* inst; int i; printf("\n\n"); printf("Please enter: database_name [user_id] [password] "\n"); (2) gets(line); if (copyWord(line, databaseName, sizeof(databaseName)) == 0) exit(0); copyWord(0, userid, sizeof(userid)); copyWord(0, password, sizeof(password)); printf("\n"); if (SQLAllocEnv(&henv) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); if (SQLAllocConnect(henv, &hdbc) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); if (SQLConnect(hdbc, (3) (SQLCHAR*)databaseName, SQL_NTS, (SQLCHAR*)userid, SQL_NTS, (SQLCHAR*)password, SQL_NTS) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); printf("Initializing . . .\n"); inst = getenv("DB2INSTANCE"); if (inst != 0 &&; strcmp(inst, "keeseyt") == 0) tableAndColumn = "KEESEY.TEST"; else tableAndColumn = "QBICDEMO.TEST"; _QbQueryCreate(&averageHandle); (4) _QbQueryAddFeature(averageHandle, "QbColorFeatureClass"); _QbQueryCreate(&histogramHandle); _QbQueryAddFeature(histogramHandle, "QbColorHistogramFeatureClass"); _QbQueryCreate(&drawHandle); _QbQueryAddFeature(drawHandle, "QbDrawFeatureClass"); (5) commandLoop(); _QbQueryDelete(drawHandle); _QbQueryDelete(histogramHandle); (10) _QbQueryDelete(averageHandle); if (SQLDisconnect(hdbc) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); if (SQLFreeConnect(hdbc) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); if (SQLFreeEnv(henv) != SQL_SUCCESS) sqlError(SQL_NULL_HSTMT); } |