如何在Android Studio的Chaquopy中安装使用Kmeans实现自适应K值图像RGB提取
在Android Studio的Chaquopy环境中实现自适应K-Means提取图像RGB值
1. 配置Chaquopy与依赖
首先在app/build.gradle中配置Chaquopy插件,并通过pip安装所需的Python库(scikit-learn用于K-Means聚类,Pillow用于图像处理):
plugins { id 'com.android.application' id 'com.chaquo.python' } android { // 保留你的Android编译、签名等原有配置 } chaquopy { defaultConfig { pythonVersion "3.10" // 选择与Chaquopy兼容的Python版本,建议3.8-3.10 pip { install "scikit-learn" install "pillow" } } }
同步Gradle项目,等待依赖安装完成。
2. 编写Python核心处理逻辑
在app/src/main/python目录下创建kmeans_rgb.py,实现图像RGB提取、自适应K值计算和聚类功能:
import numpy as np from sklearn.cluster import KMeans from PIL import Image def calculate_optimal_k(rgb_data, max_k=10): # 肘部法则:计算不同K值下的误差平方和(SSE) sse_values = [] for k in range(1, max_k + 1): kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto') kmeans.fit(rgb_data) sse_values.append(kmeans.inertia_) # 寻找SSE下降速率突变的拐点作为最佳K值 sse_deltas = np.diff(sse_values) delta_ratios = sse_deltas[:-1] / sse_deltas[1:] optimal_k = np.argmax(delta_ratios) + 2 # 转换为对应的K值 return max(optimal_k, 2) # 确保至少保留2个聚类 def get_dominant_colors(image_path, max_k=10): # 读取图像并转换为RGB格式 with Image.open(image_path) as img: img = img.convert('RGB') # 缩小图像降低计算负载,可根据需求调整尺寸 img = img.resize((120, 120), Image.Resampling.LANCZOS) # 将图像数据转换为模型所需的(n_samples, 3)数组格式 rgb_array = np.array(img).reshape(-1, 3) # 获取自适应计算的最佳K值 best_k = calculate_optimal_k(rgb_array, max_k) # 执行K-Means聚类 kmeans_model = KMeans(n_clusters=best_k, random_state=42, n_init='auto') kmeans_model.fit(rgb_array) # 提取聚类中心(即主要RGB颜色),转换为整数格式 dominant_colors = kmeans_model.cluster_centers_.astype(int).tolist() return { "optimal_k": best_k, "dominant_colors": dominant_colors }
3. Android端调用Python代码
在Activity中处理图像获取(从相册/相机),并调用Python函数获取聚类结果:
import com.chaquo.python.Python; import com.chaquo.python.android.AndroidPlatform; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class MainActivity extends AppCompatActivity { private static final String TAG = "KMeansRGBExtractor"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化Chaquopy环境 if (!Python.isStarted()) { Python.start(new AndroidPlatform(this)); } // 替换为你实际获取的图像Uri(比如从相册选择后的结果) Uri targetImageUri = ...; try { File tempImageFile = saveUriToTempFile(targetImageUri); String imagePath = tempImageFile.getAbsolutePath(); // 调用Python模块中的函数 Python pyInstance = Python.getInstance(); com.chaquo.python.PyObject result = pyInstance.getModule("kmeans_rgb") .callAttr("get_dominant_colors", imagePath, 10); // 解析返回结果 int optimalK = result.get("optimal_k").toJava(Integer.class); com.chaquo.python.PyObject colorsList = result.get("dominant_colors"); Log.d(TAG, "自适应最佳K值: " + optimalK); Log.d(TAG, "提取的主要RGB颜色: " + colorsList.toString()); // 此处可添加颜色展示、存储等后续业务逻辑 } catch (IOException e) { Log.e(TAG, "图像处理失败", e); } } // 将Uri对应的图像保存为临时文件,供Python读取 private File saveUriToTempFile(Uri uri) throws IOException { Bitmap imageBitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), uri); File tempFile = File.createTempFile("kmeans_temp", ".jpg", getCacheDir()); try (FileOutputStream fos = new FileOutputStream(tempFile)) { imageBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); } return tempFile; } }
关键注意事项
- 权限配置:针对Android 13及以下,需在
AndroidManifest.xml添加读取外部存储权限:
Android 14+可直接使用媒体库API获取图像,无需额外权限。<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/> - 性能优化:缩小图像尺寸是移动端的关键优化点,避免因图像过大导致内存不足或计算超时。
- K值范围:
max_k建议设置为5-10,既覆盖大多数场景的颜色数量,又不会过度增加计算量。 - 异常处理:实际应用中需添加图像读取失败、Python调用异常等场景的捕获与处理,提升稳定性。
内容的提问来源于stack exchange,提问作者Jyoti Prajapati
相关产品推荐
相关产品推荐

