谷歌图片搜索:如何构建反向图片搜索的URL?

12

我如何通过Java编程将图像转换为“某个字符串”,以便将其作为参数传递给Google图像搜索。 实际上,我已经在图像上进行了一些base64转换,但它与Google在其图像搜索引擎中使用的不同。 我已经进行了这样的转换(Java 7):

import javax.xml.bind.DatatypeConverter;
...
            Path p = Paths.get("my_photo.JPG");
            try(InputStream in = Files.newInputStream(p); 
                    PrintWriter write = new PrintWriter("base64.txt");
               ) {
                byte [] bytes = new byte[in.available()];
                in.read(bytes);
                String base64 = DatatypeConverter.printBase64Binary(bytes);
                write.println(base64);

            } catch(IOException ex) {
                ex.printStackTrace();
            }

这个简单程序的输出与谷歌URL中的字符串不同。我指的是那个在tbs=sbi:AMhZZ...之后的字符串。


我不明白你想要实现什么。你能给个例子吗? - mikerobi
我想使用谷歌图像搜索服务,就像http://code.google.com/intl/uk/apis/imagesearch/v1/jsondevguide.html#json_snippets_java中所示。但是,我想使用图像作为参数,而不是文本参数(注意:我不需要使用JSON,它只是在示例中使用)。 - maks
请注意,这是一个实验性的服务,您可能不想构建依赖于它的应用程序。还有其他反向图像搜索引擎 - mikerobi
抱歉,我一直在考虑将图像转换为字符串的1:1转换,而不是实际发生在搜索引擎内部的情况。我的新答案应该更有帮助。 - mikerobi
有一个[Quora上的帖子][Q]详细介绍了图像指纹算法,特别是[这个回答][Q2],作者声称曾经参与谷歌反向图像搜索功能的开发:> [该项目]使用SURF、PCA-SIFT提取关键点和描述符(浮点值向量),然后使用LSH进行索引和匹配!实际算法似乎是专有的,甚至[可能被专利保护][P]?内部系统似乎被称为“quimby”,原因可能有人可以解释一下吗?[Q]:http://www.quora.com/Algorithms/What-is-the-algorithm-used-by-Googl - André Laszlo
显示剩余2条评论
5个回答

14
这是我对图像搜索工作原理的最佳猜测:
URL中的数据并不是图像的编码形式,而是图像指纹,用于模糊匹配。
您应该注意到,当您上传图像进行搜索时,这是一个两步过程。第一步通过url http://images.google.com/searchbyimage/upload 上传图像。Google服务器返回指纹。然后将浏览器重定向到基于指纹的查询字符串的搜索页面。
除非Google公布生成指纹的算法,否则您将无法从应用程序内部生成搜索查询字符串。在此之前,您可以让应用程序将图像发布到上传URI。您应该能够解析响应并构造查询字符串。
编辑:
这些是我上传文件时发送到服务器的键和值。
image_url       =
btnG            = Search
encoded_image   = // the binary image content goes here
image_content   =
filename        =
hl              = en
bih             = 507
biw             = 1920

"bih"和"biw"看起来像是尺寸,但却不对应上传的文件。

请自己承担使用这些信息的风险。这是一个未记录的 API,可能会更改并破坏您的应用程序。


1
谢谢,我猜我知道你在说什么。你能描述一下或者举个例子,我怎样可以用图片向那个URL发送POST请求吗? - maks
1
@maks,希望我的编辑更有帮助。您需要将键/值编码为“multipart/form-data”,并将其作为POST请求正文发送。您应该能够找到许多关于如何进行编码的示例。 - mikerobi
你能否请更详细地解释一下吗?我正在尝试在WindowsPhone7上实现相同的功能。 - 1Mayur

7
Using google's image search.

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpFileUpload {
  public static void main(String args[]){
    try {
      HttpClient client = new DefaultHttpClient();
      String url="https://www.google.co.in/searchbyimage/upload";
      String imageFile="c:\\temp\\shirt.jpg";
      HttpPost post = new HttpPost(url);

      MultipartEntity entity = new MultipartEntity();
      entity.addPart("encoded_image", new FileBody(new File(imageFile)));
      entity.addPart("image_url",new StringBody(""));
      entity.addPart("image_content",new StringBody(""));
      entity.addPart("filename",new StringBody(""));
      entity.addPart("h1",new StringBody("en"));
      entity.addPart("bih",new StringBody("179"));
      entity.addPart("biw",new StringBody("1600"));

      post.setEntity(entity);
      HttpResponse response = client.execute(post);
      BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));         

      String line = "";
      while ((line = rd.readLine()) != null) {
        if (line.indexOf("HREF")>0)
      System.out.println(line.substring(8));
      }

    }catch (ClientProtocolException cpx){
      cpx.printStackTrace();
    }catch (IOException ioex){
      ioex.printStackTrace();
    }
 }
}

只需要 "encode_image" 参数,其余参数不是必需的。 - Ayman Al-Absi

4

根据 @Ajit 的回答,这个命令使用 curl 命令(适用于 Linux / Cygwin 等)实现相同的功能。

curl -s -F "image_url=" -F "image_content=" -F "filename=" -F "h1=en"  -F "bih=179" -F "biw=1600" -F "encoded_image=@my_image_file.jpg" https://www.google.co.in/searchbyimage/upload

这将在标准输出上打印一个URL。您可以使用curlwget下载该URL,但您可能需要更改用户代理为类似Chrome的图形Web浏览器。


1
这是对我有用的方法。实际上不需要任何编码。
https://www.google.com/searchbyimage?image_url=YOUR_IMAGE_URL

这是用于在线上传的图像。 - golimar

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接