You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中实现OpenCV C++的ptr<uchar>(y)及眼球检测代码?

Converting OpenCV C++ ptr<uchar> to Java and Completing the Eyeball Detection Function

In your C++ code, eye.ptr<uchar>(y) gives you a direct pointer to the start of the y-th row of the grayscale eye image. Java's OpenCV bindings don't offer direct pointer access, but we can replicate this functionality efficiently using byte arrays (since uchar maps directly to Java's byte type).

Key Replacement for ptr<uchar>

Instead of a pointer, use Mat.get(int row, byte[] buffer) to load the entire row's pixel values into a byte array. This is much faster than fetching individual pixels one by one with get(row, col).

Complete Java Implementation

Here's the full converted function, with fixes for data types and performance optimizations:

import org.opencv.core.Mat;
import org.opencv.core.Vec3f;
import org.opencv.core.MatOfVec3f;

public Vec3f getEyeball(Mat eye, MatOfVec3f circles) {
    Vec3f[] circlesArray = circles.toArray();
    int[] sums = new int[circlesArray.length];
    
    // Buffer to hold one full row of pixel data
    byte[] rowBuffer = new byte[eye.cols()];
    
    for (int y = 0; y < eye.rows(); y++) {
        // Load the entire y-th row into our buffer (replaces C++'s ptr<uchar>(y))
        eye.get(y, rowBuffer);
        
        for (int x = 0; x < eye.cols(); x++) {
            // Convert signed byte to unsigned int (matches uchar's 0-255 range)
            int pixelValue = rowBuffer[x] & 0xFF;
            
            for (int i = 0; i < circlesArray.length; i++) {
                Vec3f circle = circlesArray[i];
                // Extract and round circle parameters
                int centerX = Math.round((float) circle.val[0]);
                int centerY = Math.round((float) circle.val[1]);
                int radius = Math.round((float) circle.val[2]);
                
                // Calculate squared distance to avoid costly sqrt operations
                int dx = x - centerX;
                int dy = y - centerY;
                int squaredDistance = dx * dx + dy * dy;
                int squaredRadius = radius * radius;
                
                if (squaredDistance < squaredRadius) {
                    sums[i] += pixelValue;
                }
            }
        }
    }
    
    // Find the circle with the smallest sum of pixel values
    int smallestSum = Integer.MAX_VALUE;
    int smallestSumIndex = -1;
    for (int i = 0; i < sums.length; i++) {
        if (sums[i] < smallestSum) {
            smallestSum = sums[i];
            smallestSumIndex = i;
        }
    }
    
    return circlesArray[smallestSumIndex];
}

Important Notes

  • Unsigned Byte Handling: Java's byte is signed, so we use rowBuffer[x] & 0xFF to convert it to the correct 0-255 range that matches OpenCV's uchar.
  • Data Type Match: Your original Java code used MatOfRect, but since the C++ code uses vector<Vec3f> (storing circle centers and radii), we switched to MatOfVec3f to maintain data consistency.
  • Performance Boost: Replacing Math.pow with squared distance calculations avoids unnecessary floating-point operations, making the code faster without changing the result.

内容的提问来源于stack exchange,提问作者Blazing Forrest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:35:58